<?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/vod_favlist?%s=%s';

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

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

const IPTV_VOD_FAVSUB_URL=
    'http://%s/apiv2/vod_favsub?%s=%s&id=%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';

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;
    }

    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));
    }

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

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

        try
        {
            $this->api_call(
                sprintf(
                    IPTV_VOD_FAVADD_URL, IPTV::$SERVER,
                    $this->sid_name, $this->sid,
                    $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->api_call(
                sprintf(
                    IPTV_VOD_FAVSUB_URL, IPTV::$SERVER,
                    $this->sid_name, $this->sid,
                    $movie_id));
        }
        catch (Exception $e)
        {
            throw $this->dune_api_exception($e,
                'VOD favadd 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->director,
            $doc->film->scenario,
            $doc->film->actors,
            $doc->film->genre_str,
            $doc->film->rate_imdb,
            $doc->film->rate_kinopoisk,
            $doc->film->rate_mpaa,
            $doc->film->country,
            $doc->film->budget);

        // foreach ($doc->film->videos as $file)
        // {
          $playback_url =
              sprintf(IPTV_VOD_INFO_URL, IPTV::$SERVER,
                  $this->sid_name, $this->sid,
                  $movie_id);

          $movie->add_series_data(
              $doc->film->id,
              $doc->film->title,
              $playback_url,
              false);
        // }

        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, $page, $nums)
    {
        $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 ($query !== null)
            $url .= "&query=$query";

        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)
    {
        return $this->api_vod_list('last', null, null, $page, $nums);
    }

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

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

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

    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;
    }

    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);
    	$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->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);
    }

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

    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());
        }
    }
}

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