<?php

include_once "LN_loginext_include.php";

Class SimpleXMLExtended extends SimpleXMLElement {

    public function addCData($name, $value = NULL) {
        $new_child = $this->addChild($name);

        if ($new_child !== NULL) {
            $node = dom_import_simplexml($new_child);
            $no   = $node->ownerDocument;
            $node->appendChild($no->createCDATASection($value));
        }

        return $new_child;
    }
}

function executeRESTCall($methode, $url, $data = false, $dataType = "json", $requestHeader = array(), $authType = "mainAuth") {

//    $token = getToken();
    $curl = curl_init();
    $requestUrl = $url;

    if(empty($requestHeader)) {

        $requestHeader = array(
            'Content-Type:application/json',
            'WWW-Authenticate:'. getToken() .'',
        );

    }

    if($dataType == "json") {

        curl_setopt($curl, CURLOPT_HTTPHEADER, $requestHeader);
        curl_setopt($curl, CURLOPT_HEADER, true);

    }

    switch ($methode) {
        case 'GET':

            $requestdata = "?";

            foreach($data as $key => $value) {

                $requestdata .= urlencode($key).'='.urlencode($value).'&';

            }

            $requestUrl .= $requestdata;

            break;
        case 'POST':

            if($dataType == "xml") {

                $xmlData = new SimpleXMLExtended('<xml/>');
                array_to_xml($data,$xmlData);
                $dom = dom_import_simplexml($xmlData);
                $xml = $dom->ownerDocument->saveXML($dom->ownerDocument->documentElement);

                curl_setopt($curl, CURLOPT_POST, 1);
                curl_setopt($curl, CURLOPT_POSTFIELDS, 'orderReq='.urlencode($xml));
                curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
                curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
                curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 100);

                if(strpos($url, 'TrackingApp/track/mobile/put') == false) {

                    $myfile = fopen(getAbsoluteSystemPathLN()."/"."lnFunctionLogOrder".date("m-Y").".txt", "a");
                    fwrite($myfile, $xml);
                    fwrite($myfile, "\n".gmdate("Y-m-d\TH:i:s\Z"));
                    fwrite($myfile, "\n");
                    fclose($myfile);
                    
                } else {

                    $myfile = fopen(getAbsoluteSystemPathLN()."/"."lnFunctionLogTracking".date("m-Y").".txt", "a");
                    fwrite($myfile, $xml);
                    fwrite($myfile, "\n".gmdate("Y-m-d\TH:i:s\Z"));
                    fwrite($myfile, "\n");
                    fclose($myfile);

                }

            } else {

                curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));

            }

            break;
        case 'PUT':

            if($dataType == "xml") {

                $xmlData = new SimpleXMLElement('<xml/>');
                array_to_xml($data,$xmlData);

                curl_setopt($curl, CURLOPT_POSTFIELDS, $xmlData->asXML());
                curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
                curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);

            } else {

                curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));

            }

            break;
        case 'DELETE':
            echo "DELETE";
            break;
    }

    curl_setopt($curl, CURLOPT_URL, $requestUrl);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $methode);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    $curlResult = curl_exec($curl);

    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $body = substr($curlResult, $header_size);
    $body = json_decode($body, true);

    $headers = [];
    $output = rtrim($curlResult);
    $resultData = explode("\n",$output);
    $headers['status'] = $resultData[0];
    array_shift($resultData);

    foreach($resultData as $part){

        $middle = explode(":",$part,2);

        if(!isset($middle[1])) {

            $middle[1] = null;

        }

        $headers[trim($middle[0])] = trim($middle[1]);
    }

    if(strpos($url, 'TrackingApp/track/mobile/put') == false) {

        $myfile = fopen(getAbsoluteSystemPathLN()."/"."lnFunctionLogOrder".date("m-Y").".txt", "a");
        fwrite($myfile, json_encode($body));
        fwrite($myfile, json_encode($authType));
        fwrite($myfile, json_encode($data));
        fwrite($myfile, "\n".gmdate("Y-m-d\TH:i:s\Z"));
        fwrite($myfile, "\n");
        fclose($myfile);

    }

    if($body['status'] == 401 && ($body['error'] == "Unauthorized" || $body['error']  == "Invalid User")) {

        if($authType == "mainAuth") {

            generateToken();

            return executeRESTCall($methode, $url, $data, $dataType, $requestHeader, $authType);

        } else {

            generateAssociateToken($authType);

            if(strpos($url, 'TrackingApp/track/mobile/put') == false) {
                
                $myfile = fopen(getAbsoluteSystemPathLN()."/"."lnFunctionLogOrder".date("m-Y").".txt", "a");
                fwrite($myfile, "ELSE GENERATE ASS TOKEN");
                fwrite($myfile, $methode);
                fwrite($myfile, $url);
                fwrite($myfile, $data);
                fwrite($myfile, $dataType);
                fwrite($myfile, getAssociateToken($authType));
                fwrite($myfile, $authType);
                fwrite($myfile, "\n".gmdate("Y-m-d\TH:i:s\Z"));
                fwrite($myfile, "\n");
                fclose($myfile);

            }

            return executeRESTCall($methode, $url, $data, "json", array('Content-Type:application/json', 'WWW-Authenticate:'. getAssociateToken($authType)), $authType);

        }

    }

    return array($headers, $body);

}

function array_to_xml($data, $xml_data, $parent) {

    foreach($data as $key => $value) {

        if(is_array($value)) {

            if(is_numeric($key)) {

                $subnode = $xml_data->addChild($parent);
                array_to_xml($value, $subnode, $key);

            } else {

                if(!is_numeric(array_keys($value)[0])) {

                    $subnode = $xml_data->addChild($key);
                    array_to_xml($value, $subnode, $key);

                } else {

                    array_to_xml($value, $xml_data, $key);

                }

            }

        } else {

            if(is_numeric($key)) {

                $xml_data->addCData("$parent", htmlspecialchars("$value"));

            } else {

                $xml_data->addCData("$key", htmlspecialchars("$value"));

            }

        }
    }
}