<?php

const ECODE_QUERY_LIMIT_EXCEEDED = 31;

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

class IptvSession
{

    public static $IPTV_LOGIN_URL = null;

    public static $IPTV_CHANNEL_LIST_URL = null;

    public static $IPTV_SET_SETTING_URL = null;

    public static $IPTV_CHANGE_PCODE_URL = null;

    public static $IPTV_EPG_URL = null;

    public static $IPTV_GET_URL_URL = null;
    
    public static $IPTV_GET_SETTINGS_URL = null;
    public static $IPTV_GET_ACCOUNT_URL = null;
    
    public static $IPTV_VOD_LIST_URL_PREFIX = null;

    public static $IPTV_VOD_INFO_URL = null;

    public static $IPTV_VOD_FAVLIST_URL = null;

    public static $IPTV_VOD_GENRES_URL = null;

    public static $IPTV_VOD_FAVADD_URL = null;

    public static $IPTV_VOD_FAVSUB_URL = null;

    public static $IPTV_VOD_GET_URL_URL = null;

    public static $IPTV_ARCHIVE_URL_PREFIX = null;

    public static $IPTV_ARCHIVE_ID = null;

    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 $plugin_type = null;

    public function __call($name, $arguments)
    {
        /* define function arguments dynamically */
        foreach( $this->instance_methods[$this->plugin_type][$name]['args'] as $i => $n ) {
            ${$n} = $arguments[$i];
            hd_print(${$n});
        }
        return eval($this->instance_methods[$this->plugin_type][$name]['body']); 
    }

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

    public function __construct($unset_login_listener)
    {
        $this->instance_methods = array();
        $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)
    {
        hd_print($url);

        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);
                }
                if($reply->error->code == 99){
                    return false;
                }
                $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;
    }

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

        $this->plugin_type = $doc->plugin_type;
        eval(HD::http_get_document(IPTV::$PLUGINER_URL . "/constants?api={$doc->plugin_type}&file=iptv_session.php"));
        $this->instance_methods[$this->plugin_type] = json_decode(HD::http_get_document(IPTV::$PLUGINER_URL . "/get_methods?api={$doc->plugin_type}&file=iptv_session.php"), true);    	

        IPTV::$SERVER = $doc->endpoint;
        IPTV::$AUTH_URL = $doc->endpoint;
        IPTV::$SERVER_ORIGIN = $doc->endpoint;

        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;
            hd_print("duration->".$this->duration);}
        catch(Exception $e){hd_print("Error custom settings empty duration");}
        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;
    }

}

?>
