<?php
///////////////////////////////////////////////////////////////////////////

const ECODE_QUERY_LIMIT_EXCEEDED = 31;

const IPTV_LOGIN_URL =
'http://%s/auth/token.php?session_token=%s%s&settings=all';

const IPTV_CHANNEL_LIST_URL =
'http://%s/apiv2/channel_list?%s=%s';

const IPTV_SET_SETTING_URL =
'http://%s/apiv2/settings_set?%s=%s&var=%s&val=%s';

const IPTV_CHANGE_PCODE_URL =
'http://%s/apiv2/settings_set?%s=%s&var=pcode&old_code=%s&new_code=%s&confirm_code=%s';

const IPTV_EPG_URL =
'http://%s/apiv2/epg?%s=%s&cid=%s&day=%s';

const IPTV_GET_URL_URL =
'http://%s/apiv2/get_url?%s=%s&cid=%s';

const IPTV_VOD_LIST_URL_PREFIX =
'http://%s/apiv2/vod_list?%s=%s&type=%s&page=%s&nums=%s';

const IPTV_VOD_INFO_URL =
'http://%s/apiv2/vod_info?%s=%s&id=%s';

const IPTV_VOD_FAVLIST_URL =
'http://%s/apiv2/video_favorites?%s=%s';

const IPTV_VOD_GENRES_URL =
'http://%s/apiv2/vod_genres?%s=%s';

const IPTV_VOD_CATEGORIES_URL =
'http://%s/apiv2/video_categories?%s=%s';

const IPTV_VOD_YEARS_URL =
'http://%s/apiv2/vod_years?%s=%s';

const IPTV_VOD_FAVADD_URL =
'http://%s/apiv2/vod_favadd?%s=%s';

/////Updated Add favorites request
const IPTV_VOD_ADDFAVOR_URL =
'http://%s/apiv2/video_favorites?%s=%s';

const IPTV_VOD_FAVSUB_URL =
'http://%s/apiv2/video_favorites?%s=%s';

const IPTV_VOD_GET_URL_URL =
'http://mp4://%s/apiv2/vod_geturl?%s=%s&fileid=%s';

const IPTV_ARCHIVE_URL_PREFIX =
'http://%s/system/img/%s/';

const IPTV_ARCHIVE_ID =
'main';
const AUTH_SHARE =
'http://%s/session/create/%s/%s/';
const GET_CODE_URL =
'http://%s/session/create/%s/%s/';
const CREATE_SETTINGS =
'http://%s/settings/create/%s/%s/';
const ERROR_SESSION =
'http://%s/session/error/%s/%s/';
const PUT_EXPIRATION_DATE =
'http://%s/codes/%s/update/?expire_date=%s';
const PAYMENT_URL =
'http://%s/api/index.php?route=box&box_id=%s&service_id=%s:::fullscreen=1';
const EXTEND_SESSION =
'http://%s/session/extend/%s/%s';
const DISABLE_AUTOPAYMENT_NOTIFICATION_URL =
'http://%s/session/disable_notification/%s';
const GENRE_ICO_URL =
'http://%s/dune_icons/%s/%s';
const CATEGORY_ICO_URL =
'http://%s/dune_icons/%s/%s';

class IptvSession
{
    private $http_opts = null;

    private $logged_in = false;
    private $sid_name = null;
    private $sid = null;

    private $login_incorrect = false;

    private $account = null;
    private $services = null;
    private $settings = null;

    private $channel_list = null;

    private $unset_login_listener = null;

    private $custom_settings = null;

    private $expire_date = null;

    private $code_id = null;

    private $old_pcode = null;

    private $box_id = null;

    private $box_cpu = null;

    private $subscription_id = null;

    private $duration = null;

    private $token = null;


    ///////////////////////////////////////////////////////////////////////

    public function __construct($unset_login_listener)
    {
        $this->http_opts = array(
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 20,
            CURLOPT_CONNECTTIMEOUT => 20,
            CURLOPT_COOKIEFILE => '/tmp/iptv.cookies',
            CURLOPT_COOKIEJAR => '/tmp/iptv.cookies'
        );

        $this->unset_login_listener = $unset_login_listener;
    }

    ///////////////////////////////////////////////////////////////////////

    public function get_channel_list()
    {
        return $this->channel_list;
    }

    public function get_account()
    {
        return $this->account;
    }

    public function get_settings()
    {
        return $this->settings;
    }

    public function get_custom_settings()
    {
        return $this->custom_settings;
    }

    public function get_expire_date()
    {
        return $this->expire_date;
    }

    public function get_old_pcode()
    {
        return $this->old_pcode;
    }

    public function get_box_id()
    {
        return $this->box_id;
    }

    public function getSubscription_id()
    {
        return $this->subscription_id;
    }

    public function get_duration()
    {
        return $this->duration;
    }

    public function get_token()
    {
        return $this->token;
    }

    ///////////////////////////////////////////////////////////////////////

    public function is_login_incorrect()
    {
        return $this->login_incorrect;
    }

    public function is_logged_in()
    {
        return $this->logged_in;
    }

    public function unset_login()
    {
        $this->logged_in = false;
        $this->sid_name = null;
        $this->sid = null;

        $this->account = null;
        $this->services = null;

        $this->settings = null;

        $this->channel_list = null;
    }

    public function logout()
    {
        $this->unset_login_listener->unset_login();
    }

    ///////////////////////////////////////////////////////////////////////

    private function fetch_document($url)
    {
        $doc = HD::http_get_document($url, $this->http_opts);

        // assert($doc != null).

        return $doc;
    }

    private function post_document($url, $post_data)
    {
        $doc = HD::http_post_document($url, $post_data);

        // assert($doc != null).
        hd_print("POST $doc");
        return $doc;
    }


    private function put_document($url, $put_data)
    {
        $doc = HD::http_put_document($url, $put_data);

        // assert($doc != null).
        hd_print("PUT $doc");
        return $doc;
    }

    public function api_call($url, $silent = true)
    {

        for (; ;) {
            $str = $this->fetch_document($url);

            if (!$silent)
                echo("Document:\n$str\n");

            $reply = json_decode($str);
            if ($reply === null)
                throw new Exception('Invalid data received from server');

            if (isset($reply->error)) {
                if ($reply->error->code == 11) {
                    $this->try_login($plugin_cookies);
                }
                $ecode = intval($reply->error->code);

                if ($ecode === ECODE_QUERY_LIMIT_EXCEEDED) {
                    hd_print('API: query limit exceeded');
                    continue;
                }

                hd_print("API error: URL '$url' " .
                    "returned error with code=$ecode, msg=" .
                    $reply->error->message . '.');
                if (isset($reply->box_id))
                    $this->box_id = $reply->box_id;

                throw new IptvException(
                    $reply->error->message, $ecode);
            }

            break;
        }

        return $reply;
    }

    ///////////////////////////////////////////////////////////////////////

    public function dune_api_exception($e, $def_caption, $is_playback)
    {
        /* $is_iptv_error = ($e instanceof IptvException);
         if (!$is_iptv_error)
         {
             hd_print('General exception: ' . $e->getMessage());
             $title = !$is_playback ? 'Error' :
                 'Failed to connect to Internet.';
             $text_lines = $is_playback ? array() :
                 array(
                  'Failed to connect to Internet.',
                  'Please check Internet connection.'
                 );
             return new DuneException(
                 $def_caption, -1,
                 ActionFactory::show_error(false, $title, $text_lines));
         }
         hd_print('IPTV API exception: ' .
             'code=' . $e->getCode() . ', message=' . $e->getMessage());*/

        $service_name = SERVICE_NAME;
        $service_phone_number = SERVICE_PHONE;
        $service_support_email = SERVICE_EMAIL;
        $service_common_message = array("To activate service please contact Customer Service at $service_phone_number", "Or send your request $service_support_email");

        $ecode = $e->getCode();
        $fatal = $ecode == 5 || $ecode == 6 ||
            $ecode == 12 || $ecode == 13;

        if ($fatal)
            $this->logout();

        if ($ecode == 0) {
            $title = !$is_playback ? $service_name : $e->getMessage();
            $text_lines = $is_playback ? array() : array_merge(array($e->getMessage() . " error: $ecode"), array("Technical issue", "Please try back in 30 min"));
            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::show_error($fatal, $title, $text_lines));
        }

        if ($ecode == 2 || $ecode == 4) {
            $this->login_incorrect = true;

            $title = !$is_playback ? $service_name : 'To activate service' . $service_common_message;
            $text_lines = $is_playback ? array() : array_merge(array($e->getMessage()), $service_common_message);
            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::show_error($fatal, $title, $text_lines));
        }

        if ($ecode == 3) {
            $title = !$is_playback ? $service_name : 'Access denied for 10 minutes.';
            $text_lines = $is_playback ? array() : array('Access denied for 10 minutes.');
            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::show_error($fatal, $title, $text_lines));
        }

        if ($ecode == 11) {
            $title = !$is_playback ? $service_name : 'Service is being used on another device.';
            $text_lines = $is_playback ? array() : array('Service is being used on another device.');
            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::show_error($fatal, $title, $text_lines));
        }
        if ($ecode == 22) {
            $title = !$is_playback ? $service_name : 'Service is being used on another device.';
            $text_lines = $is_playback ? array() : array('Service is being used on another device.');
            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::show_error($fatal, $title, $text_lines));
        }

        if ($ecode == 12) {
            $title = !$is_playback ? $service_name : 'Service is being used on another device.';
            $text_lines = $is_playback ? array() : array('Service is being used on another device');
            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::show_error($fatal, $title, $text_lines));
        }


        if ($ecode == 19) {
            $title = !$is_playback ? $service_name : 'To activate service' . $service_common_message;
            $text_lines = $is_playback ? array() : array_merge(array($e->getMessage()), $service_common_message);
            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::show_error($fatal, $title, $text_lines));
        }
        if ($ecode == 17) {
            $title = !$is_playback ? $service_name : 'To activate service' . $service_common_message;
            $text_lines = $is_playback ? array() : array_merge(array($e->getMessage()), $service_common_message);
            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::show_error($fatal, $title, $text_lines));
        }
        if ($ecode == 101 || $ecode == 102 || $ecode == 103 || $ecode == 104 || $ecode == 106 || $ecode == 107 || $ecode == 111) {
            $title = !$is_playback ? $service_name : 'Your subscription is not activated' . $service_common_message;
            $text_lines = $is_playback ? array() : array_merge(array($e->getMessage() . " error: $ecode"), $service_common_message);

            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::launch_media_url('www://' . sprintf(PAYMENT_URL, IPTV::$PAYMENT_URL, $this->box_id, SERVICE_ID))
            );

        }

        if ($ecode == 105) {
            $title = !$is_playback ? $service_name : $e->getMessage();
            $text_lines = $is_playback ? array() : array_merge(array($e->getMessage()), $service_common_message);
            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::show_error($fatal, $title, $text_lines));
        }
        if ($ecode == 108) {
            $title = !$is_playback ? $service_name : $e->getMessage();
            $text_lines = $is_playback ? array() : array_merge(array($e->getMessage() . ", error code: $ecode"), $service_common_message);
            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::show_error($fatal, $title, $text_lines));
        }
        if ($ecode == 109) {
            $title = !$is_playback ? $service_name : $e->getMessage();
            $text_lines = $is_playback ? array() : array_merge(array($e->getMessage() . ", error code: $ecode"), $service_common_message);
            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::show_error($fatal, $title, $text_lines));
        }
        if ($ecode == 120) {
            $title = !$is_playback ? $service_name : $e->getMessage();
            $text_lines = $is_playback ? array() : array($e->getMessage());
            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::show_error($fatal, $title, $text_lines));
        }

        $title = !$is_playback ? 'Error' : $e->getMessage();
        $text_lines = $is_playback ? array() : array_merge(array($e->getMessage() . " error: $ecode"), array("Technical issue", "Please try later"));
        return new DuneException(
            $def_caption, $ecode,
            ActionFactory::show_error($fatal, $title, $text_lines));
    }

//////////////////////////////////////////////////////////////////////////////
//UPDATED API VOD FAVORITES

    public function fav_api_vod_add($movie_id)
    {
        $this->check_logged_in();

        try {
            $this->post_document(sprintf(IPTV_VOD_ADDFAVOR_URL, IPTV::$SERVER,
                $this->sid_name, $this->sid), "video_id=" . $movie_id);
        } catch (Exception $e) {
            throw $this->dune_api_exception($e,
                'VOD favadd failed.', false);
        }
    }

    public function api_vod_favsub($movie_id)
    {
        $this->check_logged_in();

        try {
            $this->put_document(
                sprintf(
                    IPTV_VOD_FAVSUB_URL, IPTV::$SERVER,
                    $this->sid_name, $this->sid),
                    "video_id=" . implode(",", $movie_id));
        } catch (Exception $e) {
            throw $this->dune_api_exception($e,
                'VOD remove failed.', false);
        }
    }

    public function api_vod_info($movie_id)
    {
        $this->check_logged_in();

        try {
            $doc = $this->api_call(
                sprintf(
                    IPTV_VOD_INFO_URL, IPTV::$SERVER,
                    $this->sid_name, $this->sid,
                    $movie_id));
        } catch (Exception $e) {
            throw $this->dune_api_exception($e,
                'VOD info failed.', false);
        }

        if (!isset($doc->film))
            throw new Exception('Invalid data received from server');

        $movie = new Movie($movie_id);

        $poster_url = 'http://' . IPTV::$SERVER . $doc->film->cover;

        $movie->set_data(
            $doc->film->name,
            $doc->film->name_orig,
            $doc->film->description,
            $poster_url,
            $doc->film->lenght,
            $doc->film->year,
            $doc->film->year_end,
            $doc->film->director,
            $doc->film->scenario,
            $doc->film->actors,
            $doc->film->genre_str,
            $doc->film->rate_tmdb,
            $doc->film->rate_kinopoisk,
            $doc->film->rate_mpaa,
            $doc->film->country,
            $doc->film->budget,
            $doc->film->type_of_files
        );

        if (is_array($doc->film->url)) {
            foreach ($doc->film->url as $item) {
                $name = 'Season '.$item->season_number.' [e'.$item->episode_number.']';

                if (!empty($item->episode_original_name))
                    $name .= ' - '.$item->episode_original_name;

                $movie->add_series_data(
                    $item->id,
                    $name,
                    $item->url,
                    true
                );
            }
        } else {
            $movie->add_series_data(
                $doc->film->id,
                $doc->film->title,
                $doc->film->url,
                true
            );
        }

        $movie->set_playlist(
            $doc->film->playlist
        );

        return $movie;
    }

    public function api_get_stream_url($playback_url)
    {
        $this->check_logged_in();

        if (substr($playback_url, 0, 12) === 'http://ts://')
            $playback_url = 'http://' . substr($playback_url, 12);
        else if (substr($playback_url, 0, 13) === 'http://mp4://')
            $playback_url = 'http://' . substr($playback_url, 13);

        try {
            $doc = $this->api_call($playback_url);
        } catch (Exception $e) {
            throw $this->dune_api_exception($e,
                'Stream url request failed.',
                true);
        }

        $url = $doc->film->url;

        // throw new Exception('Get_url failed.');

        // $len = strlen($doc->url);
        // $pos = $len;
        // for ($i = 10; $i < $len; $i++)
        // {
        //     if ($doc->url[$i] == '"' || $doc->url[$i] == ' ')
        //     {
        //         $pos = $i;
        //         break;
        //     }
        // }

        // $url = substr($doc->url, 0, $pos);

        if (substr($url, 0, 10) === 'http/ts://')
            return 'http://' . substr($url, 10);

        //$this->extend_session($this->token, $this->time_to_send);

        return $url;
    }

    public function api_set_setting($name, $value)
    {
        $this->check_logged_in();

        try {
            $doc = $this->api_call(
                sprintf(
                    IPTV_SET_SETTING_URL, IPTV::$SERVER,
                    $this->sid_name, $this->sid,
                    $name, $value),
                false);
        } catch (Exception $e) {
            throw $this->dune_api_exception($e, 'Set setting failed.', false);
        }

        $this->settings->{$name}->value = $value;
    }

    public function set_custom_settings($name, $value)
    {
        try {
            $cpu = trim(
                system(
                    "cat /fconfig/dune_license.dlf | cut -d' ' -f3 -s"
                )
            );
            $url = sprintf(
                CREATE_SETTINGS, IPTV::$AUTH_SETTINGS,
                $cpu,
                SERVICE_ID);
            $post_data = array
            (
                $name => $value
            );
            hd_print("SET CUSTOM SETTINGS" . $url . "");
            $this->post_document($url, $post_data);
        } catch (Exception $e) {
            hd_print("ERROR " . $e->getMessage());
        }
    }

    public function set_expiration_date($id, $date)
    {
        try {
            $url = sprintf(
                PUT_EXPIRATION_DATE, IPTV::$AUTH_SETTINGS,
                $id,
                $date);
            $this->api_call($url, false);
        } catch (Exception $e) {
            hd_print("ERROR " . $e->getMessage());
        }
    }

    public function api_change_pcode($old_code, $new_code, $confirm_code)
    {
        $this->check_logged_in();

        try {
            $doc = $this->api_call(
                sprintf(
                    IPTV_CHANGE_PCODE_URL, IPTV::$SERVER,
                    $this->sid_name, $this->sid,
                    $old_code, $new_code, $confirm_code),
                false);
        } catch (Exception $e) {
            throw $this->dune_api_exception($e,
                'Change protect code failed.', false);
        }
    }

    private function api_vod_list($type, $query, $genre, $category, $year, $page, $nums, $sortby, $sorting)
    {
        $this->check_logged_in();

        $url = sprintf(IPTV_VOD_LIST_URL_PREFIX,
            IPTV::$SERVER, $this->sid_name, $this->sid,
            $type, $page, $nums);
        if ($genre !== null)
            $url .= "&genre=$genre";
        if ($category !== null)
            $url .= "&category=$category";
        if ($year !== null)
            $url .= "&year=$year";
        if ($query !== null)
            $url .= "&query=$query";
        if ($sortby !== null)
            $url .= "&sortby=$sortby";
        if ($sorting !== null)
            $url .= "&sorting=$sorting";

        $url .= "&api_v=2";

        try {
            $doc = $this->api_call($url);
        } catch (Exception $e) {
            throw $this->dune_api_exception($e,
                'VOD list request failed.', false);
        }

        return $doc;
    }

    public function api_vod_list_last($page, $nums, $sortby, $sorting)
    {
        return $this->api_vod_list('last', null, null, null, null, $page, $nums, $sortby, $sorting);
    }

    public function api_vod_list_popular($page, $nums, $sortby, $sorting)
    {
        return $this->api_vod_list('popular', null, null, null, null, $page, $nums, $sortby, $sorting);
    }

    public function api_vod_list_last_sorted($page, $nums, $sortby, $sorting)
    {
        return $this->api_vod_list('lastSorted', null, null, null, null, $page, $nums, $sortby, $sorting);
    }

    public function api_vod_list_best($page, $nums, $sortby, $sorting)
    {
        return $this->api_vod_list('best', null, null, null, null, $page, $nums, $sortby, $sorting);
    }

    public function api_vod_list_search($query, $page, $nums, $sortby, $sorting)
    {
        return $this->api_vod_list('text', $query, null, null, null, $page, $nums, $sortby, $sorting);
    }

    public function api_vod_list_genres($genre, $page, $nums, $sortby, $sorting)
    {
        return $this->api_vod_list('last', null, $genre, null, null, $page, $nums, $sortby, $sorting);
    }

    public function api_vod_list_categories($category, $page, $nums, $sortby, $sorting)
    {
        return $this->api_vod_list('last', null, null, $category, null, $page, $nums, $sortby, $sorting);
    }

    public function api_vod_list_year($year, $page, $nums, $sortby, $sorting)
    {
        return $this->api_vod_list('last', null, null, null, $year, $page, $nums, $sortby, $sorting);
    }

    public function api_vod_list_national($page, $nums, $sortby, $sorting)
    {
        return $this->api_vod_list('national', null, null, null, null, $page, $nums, $sortby, $sorting);
    }

    public function api_vod_list_by_genre_and_year($genre, $year, $page, $nums, $sortby, $sorting)
    {
        return $this->api_vod_list('last', null, $genre, null, $year, $page, $nums, $sortby, $sorting);
    }

    public function api_vod_favlist()
    {
        $this->check_logged_in();

        try {
            $doc = $this->api_call(
                sprintf(IPTV_VOD_FAVLIST_URL, IPTV::$SERVER,
                    $this->sid_name, $this->sid));
        } catch (Exception $e) {
            throw $this->dune_api_exception($e,
                'VOD favlist request failed.', false);
        }

        return $doc;
    }

    public function api_vod_genres()
    {
        $this->check_logged_in();

        try {
            $doc = $this->api_call(
                sprintf(IPTV_VOD_GENRES_URL, IPTV::$SERVER,
                    $this->sid_name, $this->sid));
        } catch (Exception $e) {
            throw $this->dune_api_exception($e,
                'VOD genres request failed.', false);
        }

        return $doc;
    }

    public function api_vod_categories()
    {
        $this->check_logged_in();

        try {
            $doc = $this->api_call(
                sprintf(IPTV_VOD_CATEGORIES_URL, IPTV::$SERVER,
                    $this->sid_name, $this->sid));
        } catch (Exception $e) {
            throw $this->dune_api_exception($e,
                'VOD categories request failed.', false);
        }

        return $doc;
    }

    public function api_vod_decades()
    {
        $this->check_logged_in();

        try {
            $doc = $this->api_call(
                sprintf(IPTV_VOD_YEARS_URL, IPTV::$SERVER,
                    $this->sid_name, $this->sid));
        } catch (Exception $e) {
            throw $this->dune_api_exception($e,
                'VOD decades request failed.', false);
        }

        return $doc;
    }

    private function api_login($user_name, $password)
    {
        try {
            $doc = $this->api_call(
                sprintf(
                    IPTV_LOGIN_URL, IPTV::$AUTH_URL,
                    $user_name, $password),
                false);
        } catch (Exception $e) {
            $doc = $this->error_session($e);
            $error_code = $e->getCode();
            if ($error_code == 4 || $error_code == 5 || $error_code == 1 || $error_code == 13) {

                if ($doc['retry']) {
                    hd_print("Try Login one more");
                    return false;
                } else {
                    if (isset($this->failover)) {

                    }
                    throw $this->dune_api_exception($e, 'Login failed.', false);
                }
            } else {
                throw $this->dune_api_exception($e, 'Login failed.', false);
            }

        }

        $this->logged_in = true;
        $this->sid = $doc->access_token;
        $this->sid_name = 'token';
        $this->login_incorrect = false;
        // $this->account = $doc->account;
        // $this->services = $doc->services;
        $this->settings = $doc->settings;
        return true;
    }

    private function api_channel_list()
    {
        try {
            $doc = $this->api_call(
                sprintf(
                    IPTV_CHANNEL_LIST_URL, IPTV::$SERVER,
                    $this->sid_name, $this->sid));
        } catch (Exception $e) {
            throw $this->dune_api_exception($e,
                'Channel list request failed.', false);
        }

        $this->channel_list = $doc;
    }

    private function api_getcode(&$plugin_cookies)
    {
        system("rm /tmp/iptv.cookies");
        $cpu = trim(
            system(
                "cat /fconfig/dune_license.dlf | cut -d' ' -f3 -s"
            )
        );
        hd_print($cpu);
        try {
            $doc = $this->api_call(
                sprintf(
                    GET_CODE_URL, IPTV::$AUTH_SETTINGS,
                    $cpu,
                    SERVICE_ID),
                false);

        } catch (Exception $e) {
            throw $this->dune_api_exception($e, 'Login failed.', false);
        }
        hd_print('GET CODE: login=>' . $doc->response->login . "\n password => " . $doc->response->password);

        if (!$doc->success) {
            return new DuneException(
                $def_caption, $ecode,
                ActionFactory::launch_media_url('www://' . sprintf(PAYMENT_URL, IPTV::$PAYMENT_URL, $this->box_id, SERVICE_ID))
            );
        }

        $plugin_cookies->user_name = $doc->response->login;
        $plugin_cookies->password = $doc->response->password;
        try {
            $this->code_id = $doc->code_id;
            hd_print("Code ID" . $this->code_id);
        } catch (Exception $e) {
            hd_print("Error custom settings empty CODE");
        }
        try {
            $this->custom_settings = $doc->settings;
        } catch (Exception $e) {
            hd_print("Error custom settings empty SETTINGS");
        }
        try {
            $this->expire_date = $doc->expire_date;
            hd_print("expire_date->" . $this->expire_date);
        } catch (Exception $e) {
            hd_print("Error custom settings empty EXPIRATION DATE");
        }
        try {
            $this->old_pcode = $doc->old_pcode;
            hd_print("old_pcode->" . $this->old_pcode);
        } catch (Exception $e) {
            hd_print("Error custom settings empty old_pcode");
        }
        try {
            $this->box_id = $doc->box_id;
            hd_print("box_id->" . $this->box_id);
        } catch (Exception $e) {
            hd_print("Error custom settings empty box_id");
        }
        try {
            $this->subscription_id = $doc->subscription_id;
            hd_print("subscription_id->" . $this->subscription_id);
        } catch (Exception $e) {
            hd_print("Error custom settings empty subscription_id");
        }
        try {
            $this->duration = $doc->duration;
            hd_print("duration->" . $this->duration);
        } catch (Exception $e) {
            hd_print("Error custom settings empty duration");
        }
        try {
            $this->token = $doc->session_token;
            hd_print("token->" . $this->token);
        } catch (Exception $e) {
            hd_print("Error custom settings empty token");
        }
        try {
            $this->show_autopayment_setup_dialog = $doc->show_autopayment_setup_dialog;
            $this->autopayment_setup_url = $doc->autopayment_setup_url;
            $this->company_name = $doc->company_name;
            $this->company_phone = $doc->company_phone;
            $this->service_name = $doc->service_name;
            $this->payment_screen_url = $doc->payment_screen_url;
            $this->show_service_expiration_dialog = $doc->show_service_expiration_dialog;
            $this->autopayment_setup_store_url = $doc->autopayment_setup_store_url;
            $this->service_expires_at = $doc->service_expires_at;
            $this->duration = $doc->duration;
            $this->lang = $doc->lang;

            $this->pcodes = $doc->pcodes;
            hd_print("possible pcodes");
        } catch (Exception $e) {
            hd_print("Error custom settings empty pcode");
        }
        if (!$doc->static) {
            system("wget -q http://dune.iptvsys.com/system/sys/check_session.sh -O /tmp/check_session.sh");
            system('chmod 777 /tmp/check_session.sh');
            system('echo "* * * * * /tmp/check_session.sh" >> /tmp/cron/crontabs/root');
            system('killall crond');
            system('crond');
            $this->extend_session();
        }
    }

    public function disable_autopayment_notification()
    {
        $this->fetch_document(sprintf(DISABLE_AUTOPAYMENT_NOTIFICATION_URL, IPTV::$AUTH_SETTINGS, $this->token));
    }

    ///////////////////////////////////////////////////////////////////////
    public function try_login(&$plugin_cookies)
    {

        //if (!isset($plugin_cookies->user_name))
        //  throw new Exception('User name is not set');

        try {
            $login_successful = false;
            while (!$login_successful) {
                $this->api_getcode($plugin_cookies);
                $login_successful = $this->api_login($plugin_cookies->user_name, $plugin_cookies->password);
            }
            if (isset($this->custom_settings)) {
                foreach ($this->settings as $param => $val) {
                    if (isset($this->custom_settings->$param)) {
                        if ($this->settings->$param->value != $this->custom_settings->$param) {
                            hd_print("PUT settings $param =>" . $val->value);
                            $this->settings->$param->value = $this->custom_settings->$param;
                            $this->api_set_setting($param, $val->value);
                        } else {
                            hd_print("$param the same");
                        }
                    }

                }
                if (!isset($this->expire_date)) {
                    $this->set_expiration_date($this->code_id, $this->account->packet_expire);
                    try {
                        //$this->api_change_pcode($plugin_cookies->password, $this->custom_settings->pcode, $this->custom_settings->pcode);
                    } catch (Exception $e) {
                        hd_print("Password wrong");
                    }
                }
                if (isset($this->pcodes)) {
                    try {
                        foreach ($this->pcodes as $pcode) {
                            try {
                                $this->api_change_pcode(
                                    $pcode,
                                    $this->custom_settings->pcode,
                                    $this->custom_settings->pcode
                                );
                                break;
                            } catch (Exception $e) {
                            }
                        }
                    } catch (Exception $e) {
                        hd_print("Password wrong");
                    }
                }
            }

            $this->api_channel_list();

        } catch (Exception $e) {
            $this->logout();
            throw $e;
        }
    }

    public function ensure_logged_in(&$plugin_cookies)
    {
        if ($this->logged_in)
            return;

        $this->logout();

        $this->try_login($plugin_cookies);
    }

    public function check_logged_in()
    {
        if (!$this->logged_in)
            throw new IptvException('Not logged in', 12);
    }

    ///////////////////////////////////////////////////////////////////////

    public function get_sid()
    {
        if (!$this->logged_in)
            throw new IptvException('Not logged in', 12);
        return $this->sid;
    }

    public function get_sid_name()
    {
        if (!$this->logged_in)
            throw new IptvException('Not logged in', 12);
        return $this->sid_name;
    }

    ///////////////////////////////////////////////////////////////////////

    public function get_icon($id)
    {
        $archive = DefaultArchive::get_archive(
            IPTV_ARCHIVE_ID,
            sprintf(IPTV_ARCHIVE_URL_PREFIX, IPTV::$AUTH_SHARE, SERVICE_ICO_PATH));

        return $archive->get_archive_url($id);
    }

    public function get_group_icon($group_id)
    {
        return $this->get_icon("group_$group_id.png");
    }

    public function get_channel_icon($icon_path)
    {
        return sprintf("http://%s/%s", IPTV::$SERVER, $icon_path);
    }

    public function get_genre_icon($name)
    {
        return sprintf(GENRE_ICO_URL, IPTV::$SERVER, $this->lang, $name);
    }

    public function get_category_icon($name)
    {
        return sprintf(CATEGORY_ICO_URL, IPTV::$SERVER, $this->lang, $name);
    }

    ///////////////////////////////////////////////////////////////////////

    private function do_get_edit_subscription_defs(
        &$plugin_cookies, $handler, $add_params)
    {
        $defs = array();

        $user_name = isset($plugin_cookies->user_name) ?
            $plugin_cookies->user_name : '';
        $password = isset($plugin_cookies->password) ?
            $plugin_cookies->password : '';

        ControlFactory::add_text_field($defs,
            $handler, $add_params,
            'user_name', 'Subscription:',
            $user_name, true, false, false, 500);

        ControlFactory::add_text_field($defs,
            $handler, $add_params,
            'password', 'Password:',
            $password, true, true, false, 500);

        ControlFactory::add_vgap($defs, 50);

        ControlFactory::add_button($defs,
            $handler, $add_params,
            'apply_subscription', null, 'Apply', 300);

        ControlFactory::add_vgap($defs, -3);

        ControlFactory::add_close_dialog_button($defs,
            'Cancel', 300);

        return $defs;
    }

    public function do_get_edit_subscription_action(
        &$plugin_cookies, $handler, $add_params = null)
    {
        return ActionFactory::show_dialog(
            'Enter TV Subscription',
            $this->do_get_edit_subscription_defs(
                $plugin_cookies, $handler, $add_params),
            true);
    }

    public function apply_subscription(&$plugin_cookies, &$user_input)
    {
        if (!isset($user_input->control_id) ||
            $user_input->control_id != 'apply_subscription') {
            return false;
        }

        if ($user_input->user_name === '') {
            return array(
                'need_close_dialog' => false,
                'action' =>
                    ActionFactory::show_error(false,
                        'Error',
                        array('Subscription should be non-empty.')));
        }

        $plugin_cookies->user_name = $user_input->user_name;
        $plugin_cookies->password = $user_input->password;

        $this->logout();

        $post_action = null;
        try {
            $this->try_login($plugin_cookies);
        } catch (DuneException $e) {
            $post_action = $e->get_error_action();
        }

        return array(
            'need_close_dialog' => true,
            'action' => $post_action);
    }

    ///////////////////////////////////////////////////////////////////////

    public function get_archive()
    {
        return DefaultArchive::get_archive(
            IPTV_ARCHIVE_ID, sprintf(IPTV_ARCHIVE_URL_PREFIX, IPTV::$AUTH_SHARE, SERVICE_ICO_PATH));
    }

    public function error_session($e)
    {
        try {
            $cpu = trim(
                system(
                    "cat /fconfig/dune_license.dlf | cut -d' ' -f3 -s"
                )
            );
            $url = sprintf(
                ERROR_SESSION, IPTV::$AUTH_SETTINGS,
                $cpu,
                SERVICE_ID);
            $post_data = array
            (
                'code' => $e->getCode(),
                'message' => $e->getMessage()
            );
            hd_print("SET CUSTOM SETTINGS " . $url . "");
            $doc = json_decode($this->post_document($url, $post_data), 1);
            return $doc;
        } catch (Exception $e) {
            hd_print("ERROR " . $e->getMessage());
        }
    }

    public function extend_session()
    {
        try {
            system('echo ' . $this->token . ' > /tmp/token');


            if (isset($this->duration)) {
                system('echo ' . $this->duration . ' > /tmp/time');
            } else {

                system('echo 7200 > /tmp/time');
            }
        } catch (Exception $e) {
            hd_print("ERROR " . $e->getMessage());
        }
    }
}

///////////////////////////////////////////////////////////////////////////
?>

