<?php
require 'vendor/autoload.php';
include_once("config.php");

define("AWS_ACCESS_ID","AKIA5AECOUIZZIIFOQJO");
define("AWS_ACCESS_KEY","RkUyiZ8TRPO5zpb7Ujo83ROScj2usKWefChDBfwI");
define("AWS_ACCESS_URL","https://reviewnprep.s3.amazonaws.com/");


use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
// ini_set('display_errors', 1);
// ini_set('display_startup_errors', 1);
// error_reporting(E_ALL);

function converter($data)
{
    $bucket = 'reviewnprep';
    $keyname = 'us-east-1';

    $aws_access_key_id = AWS_ACCESS_ID;
    $aws_secret_access_key = AWS_ACCESS_KEY;

    $s3 = new S3Client([
        'version' => 'latest',
        'region'  => 'us-east-1',
        'credentials' => [
            'key' => $aws_access_key_id,
            'secret' => $aws_secret_access_key
        ],

    ]);
    try {
        $psp = $data['v_url'];
        $psp = str_replace(AWS_ACCESS_URL, "", $psp);

        $psp = str_replace("%20", " ", $psp);
        $psp = str_replace("%2F", "/", $psp);
        
        $explode = explode("/",$psp);
        $original_name = end($explode);
        array_pop($explode);
       
        
        // S3 bucket
        $bucket_name = $bucket;

        // aws region
        // example : 'us-east-1', 'us-east-2' etc
        $aws_region = $keyname;

        // path of file in bucket
        // example : 'records.json', 'files/test.png'
        $file_name_path = $psp;
        $psps = $original_name;
        // downloaded file name
        // example : 'records.json', 'files/test.png'
        $download_name =  "pending/" . $psps;

        /**** other variables that are automatically set ****/
        // bucket host name
        $host_name = $bucket_name . '.s3.amazonaws.com';

        // service name for S3
        $aws_service_name = 's3';

        // payload
        // no payload in this API
        $content = '';

        // UTC timestamp and date
        $timestamp = gmdate('Ymd\THis\Z');
        $date = gmdate('Ymd');



        /**** Task 1 : create canonical request for aws signature 4 ****/
        // HTTP request headers as key & value
        $request_headers = array();
        $request_headers['Host'] = $host_name;
        $request_headers['Date'] = $timestamp;
        $request_headers['x-amz-content-sha256'] = hash('sha256', $content);
       
        // sort it in ascending order
        ksort($request_headers);

        // canonical headers
        $canonical_headers = [];
        foreach ($request_headers as $key => $value) {
            $canonical_headers[] = strtolower($key) . ":" . $value;
        }
        $canonical_headers = implode("\n", $canonical_headers);

        // signed headers
        $signed_headers = [];
        foreach ($request_headers as $key => $value) {
            $signed_headers[] = strtolower($key);
        }
        $signed_headers = implode(";", $signed_headers);
        
        // cannonical request 
        $canonical_request = [];
        $canonical_request[] = "GET";
        $canonical_request[] = "/" . $file_name_path;
        $canonical_request[] = "";
        $canonical_request[] = $canonical_headers;
        $canonical_request[] = "";
        $canonical_request[] = $signed_headers;
        $canonical_request[] = hash('sha256', $content);
        $canonical_request = implode("\n", $canonical_request);
        $hashed_canonical_request = hash('sha256', $canonical_request);
        

        /**** Task 2 : creating a string to sign for aws signature 4 ****/
        // AWS scope
        $scope = [];
        $scope[] = $date;
        $scope[] = $aws_region;
        $scope[] = $aws_service_name;
        $scope[] = "aws4_request";

        // string to sign
        $string_to_sign = [];
        $string_to_sign[] = "AWS4-HMAC-SHA256";
        $string_to_sign[] = $timestamp;
        $string_to_sign[] = implode('/', $scope);
        $string_to_sign[] = $hashed_canonical_request;
        $string_to_sign = implode("\n", $string_to_sign);



        /**** Task 3 : calculating signature for aws signature 4 ****/
        // signing key
        $kSecret = 'AWS4' . $aws_secret_access_key;
        $kDate = hash_hmac('sha256', $date, $kSecret, true);
        $kRegion = hash_hmac('sha256', $aws_region, $kDate, true);
        $kService = hash_hmac('sha256', $aws_service_name, $kRegion, true);
        $kSigning = hash_hmac('sha256', 'aws4_request', $kService, true);

        // signature
        $signature = hash_hmac('sha256', $string_to_sign, $kSigning);



        /**** Task 4 : Add signature to HTTP request ****/
        // authorization
        $authorization = [
            'Credential=' . $aws_access_key_id . '/' . implode('/', $scope),
            'SignedHeaders=' . $signed_headers,
            'Signature=' . $signature
        ];
        $authorization = 'AWS4-HMAC-SHA256' . ' ' . implode(',', $authorization);

       

        /**** send HTTP request ****/
        // curl headers
        $curl_headers = ['Authorization: ' . $authorization];
        foreach ($request_headers as $key => $value) {
            $curl_headers[] = $key . ": " . $value;
        }

        $url = 'https://' . $host_name . '/' . $file_name_path;
        
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
       
        if ($http_code != 200){
            $log  = date("Y-m-d h:i:s A").' - LINE NO 175 : Error: ERROR FROM S3 OF HTTP CODE'.PHP_EOL;
                    "-------------------------".PHP_EOL.
                    //Save string to log, use FILE_APPEND to append.
                    file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
                    return;
        }else{
            $success = file_put_contents($download_name, $response);
            
            if (!$success) {
                $log  = date("Y-m-d h:i:s A").' - LINE NO 175 : Error: SAVING VIDEO FAILED'.PHP_EOL;
                        "-------------------------".PHP_EOL;
                        //Save string to log, use FILE_APPEND to append.
                        file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
                        return;
            } else {
                include_once("config.php");
                $db = new database();
                $id = $data['id'];
                
                $secondTable = $db->query("INSERT INTO `convert_start`( `convert_id`, `status`) VALUES ({$id},'1')");
                $fid = $db->query("UPDATE `convert_aws` SET `status`='S' WHERE `id` = {$id} ");

                $log  = date("Y-m-d h:i:s A").' - Video Convert Start: VideoId '.$id.PHP_EOL;
                //Save string to log, use FILE_APPEND to append.
                file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
                return true;
            }
        }
            // exit('Error : Failed to download file');

        
    } catch (S3Exception $e) {
        $log  = date("Y-m-d h:i:s A").' - LINE NO 184 : Error: '.print_r($e->getMessage(),true).PHP_EOL;
        "-------------------------".PHP_EOL;
        //Save string to log, use FILE_APPEND to append.
        file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
        return;
        // echo $e->getMessage() . PHP_EOL;
    }
}

function createPath($path) {
    if (is_dir($path)) return true;
    $prev_path = substr($path, 0, strrpos($path, '/', -2) + 1 );
    $return = createPath($prev_path);
    return ($return && is_writable($prev_path)) ? mkdir($path) : false;
}

if (!empty($_GET['cstart'])) {
    $query = $db->query("SELECT * FROM `convert_aws` WHERE `status` = 'S' ORDER BY id asc LIMIT 0,1");
    $tdata = $db->fetch_all($query);
    foreach ($tdata as $vv) {
        $id = $vv['id'];
        $db->query("UPDATE `convert_aws` SET `status`='PO' WHERE `id` = {$id} ");
        $log  = date("Y-m-d h:i:s A").' - Video Process Ongoing: VideoId '.$id.PHP_EOL;
        //Save string to log, use FILE_APPEND to append.
        file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
        converStart($vv);
    }
} else {
    $query = $db->query("SELECT * FROM `convert_aws` WHERE `status` = 'P'  ORDER BY id asc LIMIT 0,1");
    $tdata = $db->fetch_all($query);

    // Check If Any Video Start In Download Status
    $queryCheck = $db->query("SELECT * FROM `convert_start` WHERE `status` = '1'");
    $tdataCheck = $db->fetch_assoc($queryCheck);


    if (empty($tdataCheck)) {
        foreach ($tdata as $vv) {
            $id = $vv['id'];
            $db->query("UPDATE `convert_aws` SET `status`='DO' WHERE `id` = {$id} ");
            $log  = date("Y-m-d h:i:s A").' - Video Download Ongoing: VideoId '.$id.PHP_EOL;
            //Save string to log, use FILE_APPEND to append.
            file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
            converter($vv);
        }
    }
}


function converStart($data)
{

    ini_set('memory_limit', '-1');
    include_once("config.php");
    $db = new database();
    $id = $data['id'];
    require 'vendor/autoload.php';

    $bucket = 'reviewnprep';

    $aws_access_key_id = AWS_ACCESS_ID;
    $aws_secret_access_key = AWS_ACCESS_KEY;

    $s3 = new S3Client([
        'version' => 'latest',
        'region'  => 'us-east-1',
        'credentials' => [
            'key' => $aws_access_key_id,
            'secret' => $aws_secret_access_key
        ],

    ]);

    $psp = $data['v_url'];
    $psp = str_replace(AWS_ACCESS_URL, "", $psp);

    $psp = str_replace("%20", " ", $psp);

    $psp = str_replace("%2F", "/", $psp);
   
    $explode = explode("/",$psp);
   
    $original_name = end($explode);
    array_pop($explode);

    $psps = $original_name;
    
    // $psps = $psp;
    // downloaded file name
    // example : 'records.json', 'files/test.png'
    $download_name =  "pending/" . $psps;
    $direct = implode("/",$explode);
   
    $newName = "done/converted_" . time().".mp4";
    
    if (file_exists($download_name)) {
      
        try {
            $ffmpeg = FFMpeg\FFMpeg::create(array(
                'ffmpeg.binaries' => '/usr/bin/ffmpeg',
                'ffprobe.binaries' => '/usr/bin/ffprobe',
                'timeout' => 0, // The timeout for the underlying process
                'ffmpeg.threads' => 12, // The number of threads that FFMpeg should use
            ), @$logger);
            $video = $ffmpeg->open($download_name);
            // $frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(2));
            // $frame->save('image.jpg');
            $format = new FFMpeg\Format\Video\X264('libmp3lame');
            // $format->setKiloBitrate(420)->setAudioKiloBitrate(128);
            $video->save($format, $newName);
            $ffprobe = FFMpeg\FFProbe::create();
            if (!$ffprobe) {
                //Something to write to txt log
                $log = date("Y-m-d h:i:s A")." - LINE NO 318 : Error:  ".json_encode($ffprobe).$id."\n------------\n";
                //Save string to log, use FILE_APPEND to append.
                file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
            }
            $duration = $ffprobe
                ->format($newName) // extracts file informations
                ->get('duration');
            if ($duration) {
                $setDuration = $db->query("UPDATE `convert_aws` SET `duration`='{$duration}' WHERE `id` = {$id} ");
                if (!$setDuration) {
                    //Something to write to txt log
                    $log  = date("Y-m-d h:i:s A").' - LINE NO 323 : Success: update duration of video - '.$id.PHP_EOL;
                    "-------------------------".PHP_EOL.
                    //Save string to log, use FILE_APPEND to append.
                    file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
                }
            } else {
                //Something to write to txt log
                $log  = date("Y-m-d h:i:s A").' - LINE NO 330 : Error: update duration of video - '.$id.PHP_EOL;
                "-------------------------".PHP_EOL.
                //Save string to log, use FILE_APPEND to append.
                file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
            }
            
            if (file_exists($newName)) {
                // ini_set('display_errors', 1);
                // ini_set('display_startup_errors', 1);
                // error_reporting(E_ALL);
                // ini_set('memory_limit', '-1');
                unlink($download_name);
                try {
                    
                    $result = $s3->putObject(array(
                        'Bucket'       => $bucket,
                        'Key'          => $direct.'/'.$newName,
                        'SourceFile'   => $newName,
                        "ACL" => "authenticated-read",
                    ));
                   
                    unlink($newName);
                    $url = $result['ObjectURL'];
                    
                    $db->query("UPDATE `convert_aws` SET `v_url`='{$url}' WHERE `id` = {$id} ");

                    $log  = date("Y-m-d h:i:s A").' - LINE NO 311 : Success: '.$url.PHP_EOL;
                    "-------------------------".PHP_EOL;
                    //Save string to log, use FILE_APPEND to append.
                    file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
        
                    $query = $db->query("SELECT * FROM `convert_aws` WHERE `id` = '{$id}'");
                    $tdata = $db->fetch_assoc($query);
                    
                    $ch = curl_init();
        
                    curl_setopt($ch, CURLOPT_URL, "https://reviewnprep.com/Api/check_converter_status");
                    curl_setopt($ch, CURLOPT_POST, 1);
                    curl_setopt(
                        $ch,
                        CURLOPT_POSTFIELDS,
                        ["url" =>  $tdata['v_url'], "id" => $tdata['vid'],'duration'=>$duration]
                    );
                    
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        
                    $server_output = curl_exec($ch);
                    curl_close($ch);
                    $db->query("UPDATE `convert_aws` SET `status`='D' WHERE `id` = {$id} ");
                    $db->query("DELETE FROM `convert_start` WHERE `status` = '1' ");
                    $log  = date("Y-m-d h:i:s A").' - Video Convert Successfully: VideoId '.$id.PHP_EOL;
                    //Save string to log, use FILE_APPEND to append.
                    file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
                } catch (\Throwable $th) {
                    $db->query("DELETE FROM `convert_start` WHERE `status` = '1' ");
                    //Something to write to txt log
                    $log  = date("Y-m-d h:i:s A").' - LINE NO 311 : Error: '.print_r(json_encode($th->getMessage()),true).PHP_EOL;
                    "-------------------------".PHP_EOL.
                    //Save string to log, use FILE_APPEND to append.
                    file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
                    return;
                } catch(Aws\Exception\CredentialsException $e){
                    $db->query("DELETE FROM `convert_start` WHERE `status` = '1' ");
                   
                    $log  = date("Y-m-d h:i:s A").' - LINE NO 317 : Error: '.print_r(json_encode($th->getMessage()),true).PHP_EOL;
                    "-------------------------".PHP_EOL.
                    //Save string to log, use FILE_APPEND to append.
                    file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
                    return;
                }
            }
        } catch (\Exception $th) {
            
            $db->query("UPDATE `convert_aws` SET `status`='F' WHERE `id` = {$id} ");
            $db->query("DELETE FROM `convert_start` WHERE `status` = '1' ");
            $log  = date("Y-m-d h:i:s A").' - Video Convert Fail: VideoId '.$id.PHP_EOL;
                    
            $log  .= ' - LINE NO 326 : Error: '.print_r($th->getMessage(), true).PHP_EOL.
                    "-------------------------".PHP_EOL;
            //Save string to log, use FILE_APPEND to append.
            file_put_contents('/var/www/html/log/log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
            return;
        }
       
    }

    
}


if (!empty($_GET['doneCon'])) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, "http://3.133.131.241/");
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt(
        $ch,
        CURLOPT_POSTFIELDS,
        ["url" => $url, "id" => $last_id]
    );

    // In real life you should use something like:
    // curl_setopt($ch, CURLOPT_POSTFIELDS, 
    //          http_build_query(array('postvar1' => 'value1')));

    // Receive server response ...
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $server_output = curl_exec($ch);

    curl_close($ch);
}