<?php
/**
 * Classe permettant d'envoyer des donnes vers un connecteur ispi RIA en
 * mode POST par default et sous la forme d'un formulaire
 *
 * @author Administrateur
 *
 */

namespace Helpers\Webservice;
// phpcs:ignoreFile
class SendHttpRIA
{
    /**
     * Nom de l'appname RIA
     * @var string
     */
    var $appname  = '';
    /**
     * Nom du programme public RIA
     * @var string
     */
    var $prgname  = '';
    /**
     * Nom du l'argment qui sera utilis� cot� magic via la commande getParam
     * @var string
     */
    var $argument = '';
    /**
     * Method par defaut POST
     * @var string
     */
    var $method   = 'POST';
    /**
     * Definition du content type
     * @var string
     */
    var $header   = 'Content-type: application/x-www-form-urlencoded';
    /**
     * Par default le module ISPI � utiliser
     * @var string
     */
    var $ispi     = '/uniscripts/mgrqispi.dll';
    /**
     * Par default protocol HTTP
     * @var string
     */
    var $protocol = 'http';
    /**
     * Nom du host pour l'url
     * @var string
     */
    var $host     = '';
    
    var string $port = '80';

    /**
     * Document de retour XmlDocument
     * @var string|XmlDocument
     */
    var $xmlRetour = null;
    
    var bool $diag = false;
    
    public bool $useNameSpace = true;
    /**
     * Constructeur de la class
     *
     * @param string $appname  String Nom de l'appname RIA
     * @param string $prgname  String Nom du programme public RIA
     * @param string $content  String Nom du l'argment qui sera utilis� cot� magic via la commande getParam
     */
    function __construct($appname, $prgname, $content = 'content')
    {
        $this->appname  = & $appname;
        $this->prgname  = & $prgname;
        $this->argument = & $content;
    }
    
    public function setUseNameSpace(bool $value) :void
    {
        $this->useNameSpace = $value;
    }
    
    /**
     * Permet d'indiquer le protocol : http / https /ftp ....
     * @param string $protocol
     */
    function setProtocol($protocol = 'http') :void
    {
        $this->protocol = & $protocol;
    }
    
    /**
     * Determine le debug pour la page de diagnostique
     */
    function setDiag(bool $diagFlag) :void
    {
        $this->diag = $diagFlag;
    }
    
    /**
     * indiquer le nom de la machine host cibl�
     * @param string $host
     */
    function setHost(string $host = '127.0.0.1') :void
    {
        $this->host = & $host;
    }
    
    function setPort(mixed $port = '80') :void
    {
        $this->port = & $port;
    }
    
    function setIspi(string $ispi = '/uniscripts/mgrqispi.dll') :void
    {
        $this->ispi = & $ispi;
    }
    
    /**
     * indiquer la methode � utiliser POST par defaut
     * @param string $method
     */
    function setMethod(string $method = 'POST') :void
    {
        $this->method = & $method;
    }
    
    /**
     * Envoy un flux au connecteur
     *
     * <b>$object</b> peut etre une classe de type XmlDocument sinon un string
     * <b>Si le traitement est ok le contenu de retour devant etre un xml est utilisable via </b><h1>getXmlFromRia</h1>
     *
     * NE JAMAIS OPTIMISE AVEC D'AUTRE REFERENCE que celui qui est sur le param�tre 1 ($nomMetod) en effet, existe l'appel WebService SSO LEON GROSSE impossible � tester en nos locaux car pas de client
     * 
     * @param string $nomMetod
     * @param string|XmlDocument $object
     * @param mixed $headerSpecifique
     * @param mixed $modeASynchrone
     * @param mixed $NOS
     * @param mixed $vers
     * @return bool|string
     */
    function send(&$nomMetod, $object, $headerSpecifique = null, $modeASynchrone = null,  $NOS=null, $vers=null)
    {
        if (is_null($headerSpecifique)) {
            if ($object instanceof XmlDocument) {
                $data = "appname={$this->appname}&prgname={$this->prgname}&{$this->argument}=".urlencode(base64_encode($object->SaveXml()));
            } else {
                $data = "appname={$this->appname}&prgname={$this->prgname}&{$this->argument}=".urlencode(base64_encode((string)$object));
            }
                    
                    $header = $this->header;
                    $data .= '&METHOD_OXAPROC='.$nomMetod;
            if (! is_null($modeASynchrone)) {
               $data .= '&MODE='.($modeASynchrone ? 'A' : 'S'); // Spec 3582
                if ($modeASynchrone) {
                    $data .= '&CODUSR='.  urlencode($_SESSION['Session_Login']); // Spec 3582
                }
            }
        } else {
            if ($object instanceof XmlDocument) {
                $data  = $object->SaveXml();
            } else {
                $data  = & $object;
            }
                    
                    $header = & $headerSpecifique;
        }

        if($NOS != null)
        {
            $data .='&NOS='.$NOS;
        }
        if($vers != null)
        {
            $data .='&vers='.$vers;
        }
     
        $client = new \GuzzleHttp\Client(['verify' => false]);
        $response = $client->post(
            $this->protocol.'://'.$this->host.':'.$this->port.$this->ispi,
            ['headers' => [],'body' => $data]
        );

        $code = $response->getStatusCode();
        
        if (! $code) {
            return false;
        }

        $output = $response->getBody()->getContents();

        if($this->isXMLContentValid($output, '1.0', 'utf-8')) {
            $this->xmlRetour = new XmlDocument();
            $this->xmlRetour->loadXmlString($output);
            return true;
        }
        
        $this->xmlRetour = $output;
        return 'noXML';
        
       

        // $ok = false;
        // if ($fp = fopen($this->protocol.'://'.$this->host.':'.$this->port.$this->ispi.$dataString, 'r', false, stream_context_create($opts))) {
        //     $header = stream_get_meta_data($fp);
        //     if (array_key_exists('wrapper_data', $header)) {
        //         // recherche du tag ok HTTP 200 OK on va supposer que NON
        //         $longueur = -1;
        //         foreach ($header['wrapper_data'] as & $element) {
        //             if (strpos($element, ' 200 OK')>0) {
        //                 $ok = true;
        //             }
                    
        //             if (strpos($element, 'Content-Length')===0) {
        //                 $tmp = explode(':', $element);
        //                 $longueur = $tmp[1];
        //             }
        //         }
                
        //         if ($ok) {
        //             if ($longueur == -1) {
        //                 $contents = stream_get_contents($fp);
        //             } else {
        //                 $contents = stream_get_contents($fp, $longueur);
        //             }
                            
        //                     $this->xmlRetour = new XmlDocument();
                            
        //             if ($this->xmlRetour->loadXmlString($contents)) {
        //             } else {
        //                 $ok = false;
        //                 if (!$this->diag) {
        //                     @print_r($header['wrapper_data']);
        //                     echo $contents;
        //                 }
        //             }
        //         } else {
        //             @print_r($header['wrapper_data']);
        //             echo stream_get_contents($fp);
        //         }
        //     }
        //     fclose($fp);
        //     // Document xml de retour
        // }
        // return $ok;
    }
    
    public function isXMLContentValid(string $xmlContent, string $version = '1.0', string $encoding = 'utf-8') :bool
    {
        if (trim($xmlContent) == '') {
            return false;
        }

        libxml_use_internal_errors(true);

        $doc = new \DOMDocument($version, $encoding);
        $doc->loadXML($xmlContent);

        $errors = libxml_get_errors();
        libxml_clear_errors();

        return empty($errors);
    }


    function getXmlFromRia() :mixed
    {
        return $this->xmlRetour;
    }
}
