<?php
defined('BASEPATH') or exit('No direct script access allowed');
class Cron extends CI_Controller
{
    public function __construct(){
        parent::__construct();
        $this->load->model('cron_model');
        $this->load->library('vpn');
        $this->ci = & get_instance();
        $this->send_mails = SEND_EMAILS_FLAG;
    }

    // On Every 5 Minutes
    public function clean_old_sessions(){
        $where = ['timestamp <= '=>strtotime('-2 Hours')];
        $flag = $this->cron_model->deleteMySessions($where);
        if($flag){
            echo "Session cleared successfully\n";
        }else{
            echo SYSTEM_ERROR."\n";
        }

        foreach (glob('/var/lib/php/sessions/*') as $file) {
            if (is_file($file)) {
                if ((time() - filemtime($file)) >= (2 * CALC_HOURS)) {
                    unlink($file);
                    echo $file." file removed"."\n";
                }
            }
        }
    }

    /* private function expire_users($users){
        $i=0;
        if(!empty($users) && count($users) > 0){
            $wholesalers = array_column($users, 'wholesaler_user');
            if(!empty($wholesalers) && count($wholesalers) > 0){
                mylog("Deactivating Wholesalers: ".json_encode($wholesalers));
                echo ("Deactivating Wholesalers: ".json_encode($wholesalers));
                echo (is_cli()) ? "\n" : "<br>";
                foreach($wholesalers as $wholesaler){
                    $cancellation_flag = $this->vpn->cancel_renewals($wholesaler);
                    if($cancellation_flag){
                        $flag = FALSE;
                        if(fnmatch("GPA.*-*-*-*@*", $wholesaler)){
                            $key = array_search(explode('@',$wholesaler)[0], array_column($users, 'original_transaction_id'));
                            if($key !== FALSE){
                                $wholesaler = $users[$key]['user_device_id'];
                            }
                            $flag = $this->guest_user_model->deactiveSubscriptionPlanSingleById($wholesaler);
                        }else{
                            $flag = $this->guest_user_model->deactiveSubscriptionPlanSingle($wholesaler);
                        }
                        mylog("Deactivate Wholesaler: ".$wholesaler.", DB Result: ".$flag);
                        echo ("Deactivate Wholesaler: ".$wholesaler.", DB Result: ".$flag);
                        echo (is_cli()) ? "\n" : "<br>";
                        $i++;
                    }
                }
            }
        }
        return $i;
    }

    public function expire_vpn_users(){
        $list_params = [
            'action'=>'list',
            'where' => ['is_expired HAVING' => 1,'is_expired_from_sdk HAVING' => 0,'SINGLE_HAVING'=>'wholesaler_user IS NOT NULL'],
            'limit'=>2000, 'offset' => 0
        ];
        $users = $this->guest_user_model->getDatatableList($list_params);
        $user_batches = array_chunk($users, 1000);
        foreach ($user_batches as $users) {
            $counter = $this->expire_users($users);
            mylog("Total Expired Guest Users: ".$counter);
            echo ("Total Expired Guest Users: ".$counter);
            echo (is_cli()) ? "\n" : "<br>";
        }
    }

    public function expire_vpn_users_auth(){
        $list_params = [
            'action'=>'list',
            'where' => ['is_expired HAVING' => 1,'is_expired_from_sdk HAVING' => 0,'SINGLE_HAVING'=>'wholesaler_user IS NOT NULL'],
            'limit'=>2000, 'offset' => 0
        ];
        $users = $this->user_model->getDatatableList($list_params);
        $user_batches = array_chunk($users, 1000);
        foreach ($user_batches as $users) {
            $counter = $this->expire_users($users);
            mylog("Total Expired Auth Users: ".$counter);
            echo ("Total Expired Auth Users: ".$counter);
            echo (is_cli()) ? "\n" : "<br>";
        }
    } */

    public function prepare_analytics($i = 0){
        $offset = 0;
        $start_month_str = "-" . $i . " months";
        $end_month_str = "-" . ($i - 1) . " months";
        $start = strtotime(date('Y-m-01 00:00:00') . " $start_month_str") - $offset;
        $end = strtotime(date('Y-m-01 00:00:00') . " $end_month_str") - ($offset + 1); 
        $month_date_range = 'web_subscription.created_at BETWEEN ' . $start . ' AND ' . $end;
        $month = date("m",$end);
        $year = date("Y",$end);

        $trial_expired_status = ($i > 0) ? 1 : 0;
        $users = $this->user_model->getRecords(['action'=>'count']);
        $new_users = $this->user_model->getRecords(['action'=>'count','where'=>['created_at >= '=>strtotime(LATEST_DATA_CRITERIA)]]);
        $guest_users = $this->guest_user_model->getRecords(['action'=>'count']);
        $new_guest_users = $this->guest_user_model->getRecords(['action'=>'count','where'=>['device.created_at >= '=>strtotime(LATEST_DATA_CRITERIA)]]);
        $params = ['action' => 'count','where' => [
            'SINGLE_WHERE' => $month_date_range,'web_subscription.is_expired' => 0,'web_subscription.is_trial_period' => 0,
            'web_subscription.is_premium_subscription' => 1
        ]];
        $active_users = $this->user_model->getDatatableList($params);
        $params = ['action' => 'count','where' => [
            'SINGLE_WHERE' => $month_date_range,'web_subscription.is_expired' => 0,'web_subscription.is_trial_period' => 0,
            'web_subscription.is_premium_subscription' => 1
        ]];
        $active_guests = $this->guest_user_model->getDatatableList($params);
        $params = ['action' => 'count','where' => [
            'SINGLE_WHERE' => $month_date_range,'web_subscription.is_expired' => 1,
            'web_subscription.is_premium_subscription' => 1
        ]];
        $expired_users = $this->user_model->getDatatableList($params);
        $params = ['action' => 'count','where' => [
            'SINGLE_WHERE' => $month_date_range,'web_subscription.is_expired' => 1,
            'web_subscription.is_premium_subscription' => 1
        ]];
        $expired_guests = $this->guest_user_model->getDatatableList($params);
        $params = ['action' => 'count','where' => [
            'SINGLE_WHERE' => $month_date_range,'web_subscription.is_expired' => $trial_expired_status,'web_subscription.is_trial_period' => 1,
            'web_subscription.is_premium_subscription' => 1
        ]];
        $active_trial_users = $this->user_model->getDatatableList($params);
        $params = ['action' => 'count','where' => [
            'SINGLE_WHERE' => $month_date_range,'web_subscription.is_expired' => $trial_expired_status,'web_subscription.is_trial_period' => 1,
            'web_subscription.is_premium_subscription' => 1
        ]];
        $active_trial_guests = $this->guest_user_model->getDatatableList($params);

        $result = $this->cron_model->getSubscriptionAnalytics(['action'=>'count','where'=>['month'=>$month, 'year'=>$year]]);
        $analytics_data = [
            'month' => $month,
            'year' => $year,
            'users' => $users,
            'new_users' => $new_users,
            'guest_users' => $guest_users,
            'new_guest_users' => $new_guest_users,
            'active_guests' => $active_guests,
            'active_users' => $active_users,
            'expired_guests' => $expired_guests,
            'expired_users' => $expired_users,
            'active_trial_users' => $active_trial_users,
            'active_trial_guests' => $active_trial_guests
        ];
        if($result == 0){
            $flag = $this->cron_model->insertSubscriptionAnalyticsData($analytics_data);
            if(!$flag){
                mylog("Subscription Analytics Failed: ". $this->db->last_query());
            }else{
                mylog("Subscription Analytics Inserted: ". json_encode($analytics_data));
            }
        }else{
            $flag = $this->cron_model->updateSubscriptionAnalyticsData($analytics_data);
            if(!$flag){
                mylog("Subscription Analytics Failed: ". $this->db->last_query());
            }else{
                mylog("Subscription Analytics Updated: ". json_encode($analytics_data));
            }
            // mylog("Subscription Analytics Already Exist: ". json_encode($analytics_data));
        }
    }

    /* public function store_latest_analytics(){
        $trial_expired_status = 0;
        $users = $this->user_model->getRecords(['action'=>'count']);
        $new_users = $this->user_model->getRecords(['action'=>'count','where'=>['created_at >= '=>strtotime(LATEST_DATA_CRITERIA)]]);
        $guest_users = $this->guest_user_model->getRecords(['action'=>'count']);
        $new_guest_users = $this->guest_user_model->getRecords(['action'=>'count','where'=>['device.created_at >= '=>strtotime(LATEST_DATA_CRITERIA)]]);
        $params = ['action' => 'count','where' => ['web_subscription.is_expired' => 0,'web_subscription.is_trial_period' => 0]];
        $active_users = $this->user_model->getDatatableList($params);
        $params = ['action' => 'count','where' => ['web_subscription.is_expired' => 0,'web_subscription.is_trial_period' => 0]];
        $active_guests = $this->guest_user_model->getDatatableList($params);
        $params = ['action' => 'count','where' => ['web_subscription.is_expired' => 1]];
        $expired_users = $this->user_model->getDatatableList($params);
        $params = ['action' => 'count','where' => ['web_subscription.is_expired' => 1]];
        $expired_guests = $this->guest_user_model->getDatatableList($params);
        $params = ['action' => 'count','where' => ['web_subscription.is_expired' => $trial_expired_status,'web_subscription.is_trial_period' => 1]];
        $active_trial_users = $this->user_model->getDatatableList($params);
        $params = ['action' => 'count','where' => ['web_subscription.is_expired' => $trial_expired_status,'web_subscription.is_trial_period' => 1]];
        $active_trial_guests = $this->guest_user_model->getDatatableList($params);
        $params = ['web_subscription.is_trial_period' => 0,'usubscription.user_id != ' => NULL];
        $auth_revenue = $this->user_model->totalRevenue(['action'=>'row','where' => $params])['total'] ?? 0;
        $params = ['web_subscription.is_trial_period' => 0,'usubscription.user_id' => NULL];
        $guest_revenue = $this->guest_user_model->totalRevenue(['action'=>'row','where' => $params])['total'] ?? 0;

        $analytics_data = [
            'users' => $users,
            'new_users' => $new_users,
            'guest_users' => $guest_users,
            'new_guest_users' => $new_guest_users,
            'active_guests' => $active_guests,
            'active_users' => $active_users,
            'expired_guests' => $expired_guests,
            'expired_users' => $expired_users,
            'active_trial_users' => $active_trial_users,
            'active_trial_guests' => $active_trial_guests,
            'auth_revenue' => $auth_revenue,
            'guest_revenue' => $guest_revenue,
        ];
        file_put_contents(UPLOAD_PATH.'latest-analytics.json',json_encode($analytics_data));
        mylog("Analytics data stored successfully");
        mylog($analytics_data);
        echo ("Analytics data stored successfully");
        print_r($analytics_data);
        echo (is_cli()) ? "\n" : "<br>";
    } */

    public function db_backup(){
        mylog("Cron executed on ".date("Y-m-d H:i:s"));
        $ignore_tables = [
            "ci_sessions",
            "email_verifications",
            "subscription_receipts",
            "user_password_tokens"
        ];
        $ignore_tables = implode(" ",array_map(function($table){
            $table = "--ignore-table=".DB_NAME.".".$table;
            return $table;
        }, $ignore_tables));
        $cmd = "mysqldump -u ".DB_USER." -p'".DB_PASSWORD."' ".DB_NAME." ".$ignore_tables." > ".LOG_PATH."dbbackups/1134vpn-".'$(date +"%Y_%m_%d_%I_%M_%p").sql 2>&1'."\n";
        shell_exec($cmd);
    }

    public function delete_old_receipts(){
        $deleted_rows = $this->cron_model->delete_old_receipts();
        mylog($deleted_rows." receipts deleted successfully");
        echo ($deleted_rows." receipts deleted successfully");
        echo (is_cli()) ? "\n" : "<br>";
    }

    public function get_my_updated_vpn_servers(){
        $countries_filename = "countries.json";
        $countries_filepath = SITE_PATH.UPLOAD_PATH."server/".$countries_filename;
        $countries = $this->cron_model->get_my_countries();
        if($countries && !empty($countries) && count($countries) > 0){
            $countries = array_map(function($country){
                $country['updated_at'] = time();
                return $country;
            }, $countries);
            file_put_contents($countries_filepath, json_encode($countries));
        }else{
            file_put_contents($countries_filepath, json_encode([]));
        }

        $ovpn_servers_filename = "vpn-servers.json";
        $ovpn_servers_filepath = SITE_PATH.UPLOAD_PATH."server/".$ovpn_servers_filename;
        $ovpn_servers = $this->cron_model->get_my_ovpn_servers();
        if($ovpn_servers && !empty($ovpn_servers) && count($ovpn_servers) > 0){
            $ovpn_servers = array_map(function($country){
                $country['updated_at'] = time();
                return $country;
            }, $ovpn_servers);
            file_put_contents($ovpn_servers_filepath, json_encode($ovpn_servers));
        }else{
            file_put_contents($ovpn_servers_filepath, json_encode([]));
        }

        if(!empty($countries) || !empty($ovpn_servers)){
            $curlparams = [
                'url'=>WEB_URL.'cron/capture_vpn_servers',
                'method'=>'POST',
                'is_formdata' => TRUE,
                'payload'=>[
                    'countries' => new \CurlFile($countries_filepath, mime_content_type($countries_filepath), $countries_filename),
                    'ovpn_servers' => new \CurlFile($ovpn_servers_filepath, mime_content_type($ovpn_servers_filepath), $ovpn_servers_filename)
                ]
            ];
            $this->curl->call($curlparams);
            echo "Data inserted / updated successfully";
        }else{
            echo "Data already updated";
        }
        $this->db->where_in('module',['countries','vpn_servers']);
        $this->db->update('last_update',['updated_at'=>time()]);
    }

    public function capture_vpn_servers(){
        $countries_content = file_get_contents($_FILES['countries']['tmp_name']);
        $ovpn_servers_content = file_get_contents($_FILES['ovpn_servers']['tmp_name']);
        $countries = json_decode($countries_content, true);
        if($countries && !empty($countries) && count($countries) > 0){
            $this->cron_model->bulk_insert_update_countries($countries);
        }
        $ovpn_servers = json_decode($ovpn_servers_content, true);
        if($ovpn_servers && !empty($ovpn_servers) && count($ovpn_servers) > 0){
            $this->cron_model->bulk_insert_update_ovpn_servers($ovpn_servers);
        }
        $countries = $this->country_model->get_csv_list_of_inactive_countries_having_active_servers();
        if($countries){
            $countries = explode(",",$countries);
            mylog("get_csv_list_of_inactive_countries_having_active_servers");
            mylog($countries);
            if(!empty($countries) && count($countries) > 0){
                $countries = $this->country_model->make_countries_active($countries);
            }
        }
        $countries = $this->country_model->get_csv_list_of_active_countries_having_active_servers();
        if($countries){
            $countries = explode(",",$countries);
            mylog("get_csv_list_of_active_countries_having_active_servers");
            mylog($countries);
            if(!empty($countries) && count($countries) > 0){
                $this->country_model->make_countries_inactive($countries);
            }
        }
        $this->db->where_in('module',['countries','vpn_servers']);
        $this->db->update('last_update',['updated_at'=>time()]);
    }

    public function download_new_servers(){
        $active = $inactive = 0;
        $active_ip_addresses = $inactive_ip_addresses = [];

        $filepath = SITE_PATH.SERVER_FILE_UPLOAD_PATH.'latest_servers.csv';
        $ovpn_servers = file_get_contents('http://www.vpngate.net/api/iphone/');
        file_put_contents($filepath,$ovpn_servers);

        if (($handle = fopen($filepath, "r")) !== FALSE) {
            while (($server_data = fgetcsv($handle)) !== FALSE) {
                if(count($server_data) > 1 && $server_data[0] != '#HostName'){
                    $server_data = $this->cron_model->format_ovpn_server($server_data);
                    $ping_count = ping($server_data['ip_address']);
                    $server_data['ping_count'] = $ping_count;
                    if($ping_count > 0){
                        $this->cron_model->add_ovpn_server($server_data, 1);
                        $active_ip_addresses[] = $server_data['ip_address'];
                        $active++;
                    }else{
                        $this->cron_model->add_ovpn_server($server_data, 0);
                        $inactive_ip_addresses[] = $server_data['ip_address'];
                        $inactive++;
                    }
                }
            }
            fclose($handle);
            echo $message = "Temp OVPN Server Data Status: Active: ".$active.", Inactive: ".$inactive;
            mylog($message);
            mylog("Active Temp OVPN Servers: ".json_encode($active_ip_addresses));
            mylog("Inactive Temp OVPN Servers: ".json_encode($inactive_ip_addresses));
        }else{
            echo $message = "Error occured while reading file";
            mylog($message);
        }
    }

    public function check_active_servers(){
        $active_servers = $this->vpn_server_model->getRecords(['where'=>['vpn_servers.is_active'=>TRUE]]);
        if(!empty($active_servers) && count($active_servers) > 0){
            foreach ($active_servers as $server_data) {
                $ping_count = ping($server_data['ip_address']);
                $server_data['ping_count'] = $ping_count;
                if($ping_count > 0){
                    $update_data = [
                        'server_id' => $server_data['server_id'],
                        'ping_count' => $server_data['ping_count'],
                    ]; 
                    $updateFlag = $this->vpn_server_model->updateOVPNServer($update_data);
                    if(!$updateFlag){
                        mylog("Error occured while updating ping count of VPN Server : ".json_encode($update_data));
                        exit;
                    }
                }else{
                    $update_data = [
                        'server_id' => $server_data['server_id'],
                        'is_active' => $server_data['is_active'],
                        'updated_at' => time()
                    ]; 
                    $updateFlag = $this->vpn_server_model->updateOVPNServer($update_data);
                    if(!$updateFlag){
                        mylog("Error occured while updating status of VPN Server : ".json_encode($update_data));
                        exit;
                    }

                    $temp_server_params = [
                        'where'=>['temp_server.is_active'=>TRUE,'country_id'=>$server_data['country_id']],
                        'order'=>['order'=>'temp_server.ping_count','type'=>'ASC']
                    ];
                    $temp_servers = $this->temp_server_model->getRecords($temp_server_params);
                    if(!empty($temp_servers) && count($temp_servers) > 0){
                        foreach ($temp_servers as $temp_server) {
                            $ping_count = ping($temp_server['ip_address']);
                            $temp_server['ping_count'] = $ping_count;
                            if($ping_count > 0){
                                $checkIfExistOVPNServerParams = [
                                    'action'=>'row','where'=>['vpn_servers.ip_address'=>$temp_server['ip_address']]
                                ];
                                $checkIfExistOVPNServer = $this->vpn_server_model->getRecords($checkIfExistOVPNServerParams);
                                if($checkIfExistOVPNServer){
                                    if(boolval($checkIfExistOVPNServer['is_active'])){
                                        $update_data = [
                                            'server_id' => $server_data['server_id'],
                                            'ping_count' => $ping_count,
                                        ]; 
                                        $updateFlag = $this->vpn_server_model->updateOVPNServer($update_data);
                                        if(!$updateFlag){
                                            mylog("Error occured while updating ping count of VPN Server : ".json_encode($update_data));
                                            exit;
                                        }
                                    }else{
                                        $update_data = [
                                            'server_id' => $checkIfExistOVPNServer['server_id'],
                                            'ovpn' => $temp_server['ovpn'],
                                            'is_active' => TRUE,
                                            'ping_count' => $ping_count,
                                            'updated_at' => time()
                                        ]; 
                                        $updateFlag = $this->vpn_server_model->updateOVPNServer($update_data);
                                        if(!$updateFlag){
                                            mylog("Error occured while updating status of VPN Server : ".json_encode($update_data));
                                            exit;
                                        }
                                        break;                                        
                                    }
                                }else{
                                    mylog("Server ID : ".$server_data['server_id']." with ".$temp_server['ip_address']);
                                    $temp_server['server_id'] = $server_data['server_id'];
                                    $this->vpn_server_model->updateOVPNServer($temp_server);
                                    break;
                                }

                                $deleteTempServerFlag = $this->temp_server_model->deleteTempServer($temp_server['server_id']);
                                if(!$deleteTempServerFlag){
                                    mylog("Error occured while deleting Temp Server :  ".$temp_server['server_id'].", ".getDBError());
                                    exit;
                                }
                            }else{
                                $temp_server['is_active'] = FALSE;
                                $updateFlag = $this->temp_server_model->updateOVPNServer($temp_server);
                                if(!$updateFlag){
                                    mylog("Error occured while updating status of Temp Server : ".json_encode($temp_server));
                                    exit;
                                }
                            }
                        }
                    }
                }
            }
        }

        $remaining_active_servers = $this->vpn_server_model->getRemainingVPNServers();
        if(!empty($remaining_active_servers) && count($remaining_active_servers) > 0){
            foreach ($remaining_active_servers as $server_data) {
                $temp_server_params = [
                    'where'=>['temp_server.is_active'=>TRUE,'country_id'=>$server_data['country_id']],
                    'order'=>['order'=>'temp_server.ping_count','type'=>'ASC'],
                ];
                $temp_servers = $this->temp_server_model->getRecords($temp_server_params);
                if(!empty($temp_servers) && count($temp_servers) > 0){
                    $i=0;
                    foreach ($temp_servers as $temp_server) {
                        $ping_count = ping($temp_server['ip_address']);
                        $temp_server['ping_count'] = $ping_count;
                        if($ping_count > 0){
                            mylog("Deleting Server ID : ".$temp_server['server_id']);
                            $deleteTempServerFlag = $this->temp_server_model->deleteTempServer($temp_server['server_id']);
                            if(!$deleteTempServerFlag){
                                mylog("Error occured while deleting Temp Server : ".$temp_server['server_id'].", ".getDBError());
                                exit;
                            }
                            unset($temp_server['server_id']);
                            $insertVpnServerFlag = $this->cron_model->add_ovpn_server($temp_server, 1, 0);
                            if(!$insertVpnServerFlag){
                                mylog("Error occured while inserting VPN Server : ".json_encode($temp_server));
                                exit;
                            }
                            echo $message = 'VPN Server Added : '.json_encode($temp_server);
                            echo (is_cli()) ? "\n" : "<br>";
                            mylog($message);
                            $i++;
                            if($i == $server_data['remcount']){
                                break;
                            }
                        }else{
                            $temp_server['is_active'] = FALSE;
                            $updateFlag = $this->temp_server_model->updateOVPNServer($temp_server);
                            if(!$updateFlag){
                                mylog("Error occured while updating status of Temp Server : ".json_encode($temp_server));
                                exit;
                            }
                        }
                    }
                }
            }
        }
        echo 'Script executed';
    }

    public function check_temp_servers(){
        $active_servers = $this->temp_server_model->getRecords(['where'=>['temp_server.is_active'=>FALSE]]);
        if(!empty($active_servers) && count($active_servers) > 0){
            foreach ($active_servers as $server_data) {
                $ping_count = ping($server_data['ip_address']);
                $server_data['ping_count'] = $ping_count;
                if($ping_count > 0){
                    $update_data = [
                        'server_id' => $server_data['server_id'],
                        'ping_count' => $server_data['ping_count'],
                        'is_active' => TRUE,
                    ]; 
                    $updateFlag = $this->temp_server_model->updateOVPNServer($update_data);
                    if(!$updateFlag){
                        mylog("Error occured while updating status of Temp Server : ".json_encode($update_data));
                        exit;
                    }
                }else{
                    mylog("Inactive Temp Server : ".json_encode($server_data));
                }
            }
        }
        echo 'Script executed';
    }

    public function generate_premium_servers_report(){
        $url = 'https://vpnsuper.vpngn.com/api/serverlist/';
        $content = file_get_contents($url);
        $servers = json_decode($content, true);
        $active = $inactive = [];
        if(!empty($servers) && count($servers) > 0){
            foreach ($servers as $server) {
                $temp = [
                    'flag' => $server['flag'],
                    'name' => $server['name'],
                    'country' => $server['country'],
                    'ip' => $server['ip'],
                    'hostname' => $server['hostname'],
                    'protocols' => json_encode($server['protocols']),
                ];
                $ping_status = ping($server['ip']);
                if($ping_status > 0){
                    $active[] = $temp;
                }else{
                    $inactive[] = $temp;
                }
                $active[] = $temp;
            }
            
            array_multisort(array_column($active, 'name'), SORT_NATURAL, $active);
            array_multisort(array_column($inactive, 'name'), SORT_NATURAL, $inactive);
            $this->load->view('emails/premium-server-report', ['active_servers'=>$active, 'inactive_servers'=>$inactive]);
        }else{
            echo 'Data not found';
        }
    }
    
    public function generate_basic_servers_report(){
        $servers = $this->vpn_server_model->getRecords(['where'=>['vpn_servers.is_active'=>TRUE]]);
        pre($servers);
        $active = $inactive = [];
        if(!empty($servers) && count($servers) > 0){
            foreach ($servers as $server) {
                $temp = [
                    'flag' => $server['flag'],
                    'name' => $server['name'],
                    'country' => $server['country'],
                    'ip' => $server['ip'],
                    'hostname' => $server['hostname'],
                    'protocols' => json_encode($server['protocols']),
                ];
                $ping_status = ping($server['ip']);
                if($ping_status > 0){
                    $active[] = $temp;
                }else{
                    $inactive[] = $temp;
                }
                $active[] = $temp;
            }
            
            array_multisort(array_column($active, 'name'), SORT_NATURAL, $active);
            array_multisort(array_column($inactive, 'name'), SORT_NATURAL, $inactive);
            $this->load->view('emails/premium-server-report', ['active_servers'=>$active, 'inactive_servers'=>$inactive]);
        }else{
            echo 'Data not found';
        }
    }

    public function update_ovpn_file(){
        $temp_servers = $this->temp_server_model->getRecords();
        if(!empty($temp_servers) && count($temp_servers) > 0){
            foreach ($temp_servers as $server_data) {
                $update_data = ['server_id'=>$server_data['server_id'], 'ovpn'=>get_ovpn_file_content($server_data['ovpn'], $server_data['ip_address']), 'updated_at'=>time()];
                $flag = $this->temp_server_model->updateOVPNServer($update_data);
                if(!$flag){
                    mylog("Error occured while updating status of Temp Server : ".json_encode($update_data));
                    exit;
                }
            }
        }
        $vpn_servers = $this->vpn_server_model->getRecords();
        if(!empty($vpn_servers) && count($vpn_servers) > 0){
            foreach ($vpn_servers as $server_data) {
                $update_data = ['server_id'=>$server_data['server_id'], 'ovpn'=>get_ovpn_file_content($server_data['ovpn'], $server_data['ip_address']), 'updated_at'=>time()];
                $flag = $this->vpn_server_model->updateOVPNServer($update_data);
                if(!$flag){
                    mylog("Error occured while updating status of VPN Server : ".json_encode($update_data));
                    exit;
                }
            }
        }
    }
    
    public function get_my_active_wholesaler_userdata(){
        $params = [
            'where' => [
                'web_subscription.is_latest_webhook' => 1,
                'web_subscription.is_expired' => 0,
                'SINGLE_HAVING' => 'wholesaler_user IS NOT NULL',
                'web_subscription.is_premium_subscription' => 1
            ]
        ];
		/* $params = [
			'where' => [
				'web_subscription.is_latest_webhook' => 1,
                'web_subscription.product_id IN' => ['com.optimal.vpn.streamingmonth','com.optimal.vpn.streamingyear'],
                'device.is_expired_from_sdk' => 0,
				'wholesaler_user HAVING_LIKE' => 'TEST--%',
			]
		]; */

		// get data
		$wholesalers = $this->user_model->get_active_users($params);

        //csv file name
		$filename = 'wholesalers_'.date('Ymd').'.csv';
		header("Content-Description: File Transfer");
		header("Content-Disposition: attachment; filename=$filename");
		header("Content-Type: application/csv; "); 

		// file creation
		$file = fopen('php://output', 'w');

		$header = [
            "#","Wholesaler User","Notification Type","Subscription Type","Org.Transaction ID","Transaction ID","Org.Purchase Date","Purchase Date","Exp.Date",
            "Cancelled On", "Trial Mode","Is Expired?","Device Uniq.ID","Device Name", "Device Token", "Device Type", "App Version"
        ];
		fputcsv($file, $header);

		$i = 0;
		foreach ($wholesalers as $wholesaler){
			$tempdata = [
				++$i,
                str_replace("TEST--","",$wholesaler['wholesaler_user']),
                $wholesaler['notification_type'],
                $wholesaler['product_id'],
                $wholesaler['original_transaction_id'],
                $wholesaler['transaction_id'],
                date('Y-m-d H:i:s',($wholesaler['original_purchase_date_ms']/1000)),
                date('Y-m-d H:i:s',($wholesaler['purchase_date_ms']/1000)),
                date('Y-m-d H:i:s',($wholesaler['expires_date_ms']/1000)),
                date('Y-m-d H:i:s',($wholesaler['cancellation_date_ms']/1000)),
                boolval($wholesaler['is_trial_period']) ? "Yes" : "No",
                boolval($wholesaler['is_expired']) ? "Yes" : "No",
                $wholesaler['device_unique_id'],
                $wholesaler['device_name'],
                $wholesaler['device_token'],
                $wholesaler['device_type'],
                $wholesaler['app_version'],
			];
		 	fputcsv($file,$tempdata);
		}

		fclose($file);
		exit;
	}

    public function expire_inactive_wholesalers(){
		$params = [
			'where' => [
				'web_subscription.is_latest_webhook' => 1,
                'web_subscription.is_premium_subscription' => 1,
                'device.is_expired_from_sdk' => 0,
                'web_subscription.is_expired' => 1,
                'web_subscription.expires_date_ms <=' => (time() * 1000),
                // 'SINGLE_WHERE'=>'device.wholesaler_user IS NULL'
            ],
            'order' => ['order'=>'web_subscription.webhook_subscription_id','type'=>'ASC'],
            'limit' => 1000,
            'offset' => 0,
		];
        
		// get data
		$wholesalers = $this->user_model->get_active_users($params);
        $counter = $this->expire_wholesalers($wholesalers);
        mylog("Total Expired Wholesalers: ".$counter);
        echo ("Total Expired Wholesalers: ".$counter);
        echo (is_cli()) ? "\n" : "<br>";
	}

    public function active_expired_wholesalers(){
		$params = [
			'where' => [
				'web_subscription.is_latest_webhook' => 1,
                'web_subscription.is_premium_subscription' => 1,
                'device.is_expired_from_sdk' => 1,
                'web_subscription.is_expired' => 0,
                'web_subscription.expires_date_ms >' => (time() * 1000),
                'web_subscription.notification_type !=' => 'CANCEL',
                // 'SINGLE_WHERE'=>'device.wholesaler_user IS NULL'
            ],
            'order' => ['order'=>'web_subscription.webhook_subscription_id','type'=>'ASC'],
            'limit' => 500,
            // 'offset' => 0,
		];
        
		// get data
		$wholesalers = $this->user_model->get_active_users($params);
        $counter = $this->active_wholesalers($wholesalers);
        mylog("Total Expired Users: ".$counter);
        echo ("Total Expired Users: ".$counter);
        echo (is_cli()) ? "\n" : "<br>";
	}

    private function active_wholesalers($wholesalers){
        $i=0;
        $wholesaler_users = array_column($wholesalers, 'wholesaler_user');
        mylog("Activating Wholesalers: ".json_encode($wholesaler_users));
        echo ("Activating Wholesalers: ".json_encode($wholesaler_users));
        echo (is_cli()) ? "\n" : "<br>";
        if(!empty($wholesalers) && count($wholesalers) > 0){
            foreach($wholesalers as $wholesaler_user){
                $wholesaler = $wholesaler_user['wholesaler_user'];
                // $monthly_plans = ['com.optimal.vpn.month','com.optimal.vpn.streamingmonth','com.test.vpnblue.month','com.test.vpnblue.stream.month'];
                $monthly_plans = ['com.optimal.vpn.streamingmonth','com.V3Pgq6rK.streaming.monthly'];
                // $yearly_plans = ['com.optimal.vpn.year','com.optimal.vpn.streamingyear','com.test.vpnblue.yearly','com.test.vpnblue.stream.yearly'];
                $yearly_plans = ['com.optimal.vpn.streamingyear','com.V3Pgq6rK.streaming.yearly'];
                if(in_array($wholesaler_user['product_id'],$monthly_plans)){
                    $this->vpn->renew($wholesaler_user['wholesaler_user'], 1);
                }elseif(in_array($wholesaler_user['product_id'],$yearly_plans)){
                    $this->vpn->renew($wholesaler_user['wholesaler_user'], 12);
                }
                
                $flag = FALSE;
                $wholesaler_id = $wholesaler_user['user_device_id'];
                $flag = $this->guest_user_model->activeSubscriptionPlan($wholesaler_id);
                mylog("Activate Wholesaler: ".$wholesaler.", DB Result: ".$flag);
                echo ("Activate Wholesaler: ".$wholesaler.", DB Result: ".$flag);
                echo (is_cli()) ? "\n" : "<br>";
                $i++;
            }
        }
        return $i;
    }

    private function expire_wholesalers($wholesalers){
        $i=0;
        $wholesaler_users = array_column($wholesalers, 'wholesaler_user');
        mylog("Deactivating Wholesalers: ".json_encode($wholesaler_users));
        echo ("Deactivating Wholesalers: ".json_encode($wholesaler_users));
        echo (is_cli()) ? "\n" : "<br>";
        if(!empty($wholesalers) && count($wholesalers) > 0){
            foreach($wholesalers as $wholesaler_user){
                $wholesaler = $wholesaler_user['wholesaler_user'];
                // $cancellation_flag = $this->vpn->cancel_renewals($wholesaler);
                $cancellation_flag = $this->vpn->close_account($wholesaler);
                if($cancellation_flag){
                    $flag = FALSE;
                    $wholesaler_id = $wholesaler_user['user_device_id'];
                    $flag = $this->guest_user_model->deactiveSubscriptionPlanSingleById($wholesaler_id);
                    mylog("Deactivate Wholesaler: ".$wholesaler.", DB Result: ".$flag);
                    echo ("Deactivate Wholesaler: ".$wholesaler.", DB Result: ".$flag);
                    echo (is_cli()) ? "\n" : "<br>";
                    $i++;
                }
            }
        }
        return $i;
    }

    public function capture_subscription_stats(){
        $analytics = $this->subscription_model->getLatestSubscriptionStatsStoreWise();
        $stat_date = date('Y-m-d', strtotime('yesterday'));
        $stat_where = ['stat_date'=>$stat_date,'store' => APP_STORE_APPLE];
        $rows = $this->subscription_model->getMySubscriptionStats(['action'=>'count','where'=>$stat_where]);
        if($rows == 0){
            $analytics_data = [
                'store' => APP_STORE_APPLE,
                'stat_date' => $stat_date,
                'paid_subscribers' => $analytics[APP_STORE_APPLE]['paid_subscribers'],
                'trial_subscribers' => $analytics[APP_STORE_APPLE]['trial_subscribers'],
                'expired_subscribers' => $analytics[APP_STORE_APPLE]['expired_subscribers']
            ];
            $flag = $this->subscription_model->insertSubscriptionStatsData($analytics_data);
            if(!$flag){
                return false;
            }
        }else{
            $flag = $this->subscription_model->updateSubscriptionStatsData($analytics[APP_STORE_APPLE], $stat_where);
            if(!$flag){
                return false;
            }
        }
        $stat_where = ['stat_date'=>$stat_date,'store' => APP_STORE_ANDROID];
        $rows = $this->subscription_model->getMySubscriptionStats(['action'=>'count','where'=>$stat_where]);
        if($rows == 0){
            $analytics_data = [
                'store' => APP_STORE_ANDROID,
                'stat_date' => $stat_date,
                'paid_subscribers' => $analytics[APP_STORE_ANDROID]['paid_subscribers'],
                'trial_subscribers' => $analytics[APP_STORE_ANDROID]['trial_subscribers'],
                'expired_subscribers' => $analytics[APP_STORE_ANDROID]['expired_subscribers']
            ];
            $flag = $this->subscription_model->insertSubscriptionStatsData($analytics_data);
            if(!$flag){
                return false;
            }
        }else{
            $flag = $this->subscription_model->updateSubscriptionStatsData($analytics[APP_STORE_ANDROID], $stat_where);
            if(!$flag){
                return false;
            }
        }
        echo json_encode($analytics);
    }

    public function daily_subscription_stats_email(){
        $date = date('Y-m-d', strtotime('yesterday'));
        $apple_data = $this->subscription_stat_model->apple_subscription_stats($date);
        $android_data = $this->subscription_stat_model->android_subscription_stats($date);

        $template = $this->load->view('emails/daily_subscription_email',array('apple_data'=>$apple_data,'android_data'=>$android_data,'date'=>$date), TRUE);
        $subject = 'Daily Subscription Statistics';

        $params = [
            "from" => MY_SMTP_FROM_EMAIL,
            "to" => ANALYTICS_REPORT_TO,
            "cc" => ANALYTICS_REPORT_CC,
            "bcc" => ANALYTICS_REPORT_BCC,
            "subject" => $subject,
            "message" => $template,
        ];
        $result = $this->sendmail->send_email_with_params($params);
        if(!$result){
            return false;
        }
    }

    public function monthly_subscription_stats_email(){
        $start = date('Y-m-01',strtotime('-1 month'));
        $end = date('Y-m-01');
        $total_date = $this->subscription_stat_model->monthly_dates($start,$end);
        foreach($total_date as $key => $date){
            $date = $date->stat_date;
            // IOS
            $apple_monthly_sub_stat = $this->subscription_stat_model->monthly_apple_subscription_stat($date);
            $total_date[$key]->apple_monthly = $apple_monthly_sub_stat;
            // ANDROID
            $android_monthly_sub_stat = $this->subscription_stat_model->monthly_android_subscription_stat($date);
            $total_date[$key]->android_monthly = $android_monthly_sub_stat;
        }
        $total_ios_stats = $this->subscription_stat_model->total_ios_stats($start,$end);
        $total_android_stats = $this->subscription_stat_model->total_android_stats($start,$end);

        $template = $this->load->view('emails/monthly_subscription_stat_email',array('total_date'=>$total_date,'total_ios'=>$total_ios_stats,'total_android'=>$total_android_stats), TRUE);
        $subject = 'Monthly subscription Statistics';

        $params = [
            "from" => MY_SMTP_FROM_EMAIL,
            "to" => ANALYTICS_REPORT_TO,
            "cc" => ANALYTICS_REPORT_CC,
            "bcc" => ANALYTICS_REPORT_BCC,
            "subject" => $subject,
            "message" => $template,
        ];
        $result = $this->sendmail->send_email_with_params($params);
        if(!$result){
            return false;
        }
    }
}