<?php
require_once __DIR__ . '/AmazonAWS.class.inc';

/**
 * \file AmazonApiGateway.php
 * \brief Class to use API Gateway FME cloud
 *
 * \author Frederic Carretero <frederic.carretero@veremes.com>
 */

Class AmazonApiGateway extends AmazonAWS {
    const API_COMPONENT_SERVICE = 'execute-api';
    public $sRestApiId; // Identifiant de l'API.
    public $sStageName; // Nom de l'étape d'un déploiement de l'API.
    
    /**
     * construct
     * @param {string} $sAwsAccessKeyId Access key ID.
     * @param {string} $sAwsSecretAccessKey Secret access key.
     * @param {string} $sAwsRegion Region.
     * @param {string} $sRestApiId API identifier.
     * @param {string} $sStageName Stage name of an API deployment.
     */
    function __construct ($sAwsAccessKeyId, $sAwsSecretAccessKey, $sAwsRegion, $sRestApiId, $sStageName) {
        // Paramètres obligatoires de la classe mère AmazonAWS.
        parent::__construct($sAwsAccessKeyId, $sAwsSecretAccessKey, $sAwsRegion);
        // Paramètres pour l'url racine de l'API.
        $this->sRestApiId = $sRestApiId;
        $this->sStageName = $sStageName;
        //if($sAwsRegion == 'us-east-1')
            //$this->sHost = trim('' . self::API_COMPONENT_SERVICE . '.amazonaws.com');
        //else
            $this->sHost =  trim($sRestApiId . '.' . self::API_COMPONENT_SERVICE . '.' . $sAwsRegion . '.amazonaws.com');
    }
    
    /**
     * Generating all the headers for the request. Deprecated.
     * @return Headers for request.
     */
    function generateRequestHeaders() {
        $sTimestamp = time();
        // Entêtes obligatoires.
        $sXAmzDate = gmdate('Ymd\THis\Z', $sTimestamp);
        $sDate = gmdate('Ymd', $sTimestamp);
        // Charge utile vide hachée.
        $sRequestPayload = '';
        
        // 1. Création d'une demande canonique pour Signature V4.
        $sHttpRequestMethod = 'GET';
        $sCanonicalUri = str_replace('%2F', '/', rawurlencode('/' . $this->sStageName));
        $sCanonicalQueryString = '';
        $sCanonicalHeaders = 'host:' . $this->sHost . chr(10) .
                            'x-amz-date:' . $sXAmzDate . chr(10);
        $sSignedHeaders = 'host;x-amz-date';
        $sHashedPayload = hash(self::HASHING_ALGORITHM, $sRequestPayload, false);
        $sCanonicalRequest = $sHttpRequestMethod . chr(10) .
                            $sCanonicalUri . chr(10) .
                            $sCanonicalQueryString . chr(10) .
                            $sCanonicalHeaders . chr(10) .
                            $sSignedHeaders . chr(10) .
                            $sHashedPayload;

        // 2. Création d'une chaîne à signer pour Signature V4.
        $sStringToSign = $this->createStringToSign($sDate, $sTimestamp, $sCanonicalRequest, self::API_COMPONENT_SERVICE);

        // 3. Calcul de la signature pour AWS Signature V4.
        $sSigningKey = $this->createSigningKey(self::API_COMPONENT_SERVICE, $sDate);
        $sSignature = $this->calculateSignature($sStringToSign, $sSigningKey);

        // 4. Création de l'entête "Authorization" pour la requête.
        $sCredentialScope = $this->createCredentialScope($sDate, self::API_COMPONENT_SERVICE);
        $sAuthorizationHeader = $this->generateAuthorizationHeader($this->sHashingAlgorithmString, $sCredentialScope, $sSignedHeaders, $sSignature);

        // Entêtes pour la requete.
        $aHeaders = array(
            'Authorization: ' . $sAuthorizationHeader,
            'X-Amz-Date: ' . $sXAmzDate
        );
        /*
        echo PHP_EOL . 'Canonical request:' . PHP_EOL;
        print_r($sCanonicalRequest);
        echo PHP_EOL . PHP_EOL . 'String To Sign:' . PHP_EOL;
        print_r($sStringToSign);
        */
        return $aHeaders;
    }

    function generateGatewayRequestHeaders($sMethod, $sUrl, $aAddedHeaders, $mParams, $bValuesAsFormData = false) {

        $sParams = '';

        //stringify params if it's an array of depth = 1 else value = array
        if(!empty($mParams) && !$bValuesAsFormData){
            if(is_array($mParams)){
                foreach ($mParams as $sKey => $sValue) {
                    $sParams .= urlencode($sKey);
                    $sParams .= "=";
                    $sParams .= urlencode($sValue);
                    $sParams .= '&';
                }
                $sParams = substr($sParams, 0, -1);
                $aAddedHeaders[] = 'Content-Type: application/x-www-form-urlencoded';
            } else {
                $sParams = $mParams;
            }
        }

        $sUrlParameter = "/";

        if(strpos($sUrl, "/") === 1){
            $sUrlParameter = "";
        }

        // build sFullUrl
        if(strpos($sUrl, $this->sHost) === -1){
            $sUrl = 'https://' . $this->sHost . $sUrlParameter . $sUrl;
        }

        $sFullUrl = $sMethod . ' ' . $sUrl . ' HTTP/1.1'; 
        
        return $this->generateAwsSignedHeaders($sFullUrl, $this->sHost, self::API_COMPONENT_SERVICE, $aAddedHeaders, $sParams);
    }
}
?>