<?php
/**
 */
class NemTilmeldAPIClient {
    const HASH_ALGO = 'sha256';
    const AUTHORIZATION_SCHEME = 'NemTilmeld';
    
    private $base_address;
    private $username;
    private $secret;
    private $api_version = 1;
    private $http_date;
    private $nonce;
    
    
    
    //variables to keep return codes etc.
    private $return_code;
    
    public function __construct($domain = null, $username = null, $secret = null, $api_version = NULL) {
        if ( !empty($domain) && !empty($username) && !empty($secret)) {
            $base_address = 'https://'.$domain;
            if (filter_var($base_address, FILTER_VALIDATE_URL) !== false) {
                $this->base_address = $base_address;
                $this->username = $username;
                $this->secret = $secret;
                $this->api_version = $api_version;
            } else {
                throw new Exception("Invalid domain name specified, unable to construct a valid URL.");
            }
        } else {
            throw new Exception("Invalid arguments, all arguments are required");
        }
    }
    
    public function get($request) {
        //clear return values.
        $this->return_code = null;  
        //sanitize the request address (must start with /.
        if ( !empty($request) ) {   
            if ( substr($request, 0, 1) !== '/') {
                $request = '/'.$request;
            }
            if ( substr($request, 0, 5) !== '/api/') {
                $request = '/api'.$request;
            }
            //build headers
            $headers = $this->createHeaders('GET', $request, $body = null);
           
            $ch = curl_init($this->base_address.$request);
            $options = array ( CURLOPT_HTTPGET => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_VERBOSE => 0, CURLOPT_HTTPHEADER => $headers);
            curl_setopt_array($ch, $options);
            $result = curl_exec($ch);
            $this->return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE );
            if ( $result !== false  && $this->return_code === 200) {
                if (!empty($result) ) {
                    return $result;    
                }
            } 
            curl_close($ch);
        }
        return false;
    }

    public function post($request, $message_body) {
        //clear return values.
        $this->return_code = null;  
        //sanitize the request address (must start with /.
        if ( !empty($request) ) {   
            if ( substr($request, 0, 1) !== '/') {
                $request = '/'.$request;
            }
            if ( substr($request, 0, 5) !== '/api/') {
                $request = '/api'.$request;
            }
            //build headers
            $headers = $this->createHeaders('POST', $request, $message_body);
           
            $ch = curl_init($this->base_address.$request);
            $options = array ( CURLOPT_POST => true, CURLOPT_POSTFIELDS => $message_body, CURLOPT_RETURNTRANSFER => true, CURLOPT_VERBOSE => 0, CURLOPT_HTTPHEADER => $headers);
            curl_setopt_array($ch, $options);
            $result = curl_exec($ch);
            $this->return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE );
            if ( $result !== false  && ($this->return_code === 200 || $this->return_code === 400)) {
                if (!empty($result) ) {
                    return $result;    
                }
            } 
            curl_close($ch);
        }
        return false;
    }

    
    
    public function getResponseCode (){
        return  $this->return_code;  
    }
        
    private function createAuthentication($method, $path, $body = null) {
        $strings_to_hash = array();
        $strings_to_hash[] = $method;
        $strings_to_hash[] = $path;
        $strings_to_hash[] = $this->http_date;
        $strings_to_hash[] = $this->nonce;
        $strings_to_hash[] = $this->api_version;        
        $strings_to_hash[] = $body; 
        $digest = hash_hmac(NemTilmeldAPIClient::HASH_ALGO, implode("\n", $strings_to_hash), $this->secret);
        return 'Authorization: '.NemTilmeldAPIClient::AUTHORIZATION_SCHEME.' '.$this->username.':'.$digest;
    }
    
     private function createHeaders($method, $request, $body) {
        $headers = array();        
        $now = new Datetime();
        $this->http_date = gmdate('D, d M Y H:i:s', time()).' GMT';
        $this->nonce = $now->format('Uv');
        $headers[] = 'Date: '.$this->http_date;
        $headers[] = 'API-Version: '.$this->api_version;
        $headers[] = 'Nonce: '.$this->nonce;
        $headers[] = $this->createAuthentication($method, $request, $body);
        return $headers;
    }
}

?>