<?php

/*
 *
 * Class: iapiHandler
 * 
 * Klasa koja priprema i izvrsava upit API funkciji.  
 *
 * Sadrzi metod Execute() kojim se upit prosledjuje API severu. 
 * Upit moze biti objekat tipa iapiQueryEnvelope, niz koji odgovara strukuri API upita ili,
 * string koji sadrzi JSON odgovarajuce strukture.
 *   
 */ 
 
include_once ('iapi_response_envelope_class.php'); 

class iapiHandler {

	public $APIServerURL = '';	
	public $DebugLevel = 0;
	public $DebugSections = '';
  public $RequestAPIVersion = API_VERSION;
  
  public $SaveRequestJSONToFile = false;

  private $LastQueryString = '';
  
  function GetLastQueryString() {
      return $this->LastQueryString;
  }
  
  private $LastResponseString = '';
  private $ContentType = '';
  
  function GetLastResponseString() {
      return $this->LastResponseString;
  }    

	function Execute($pQuery = '', 
                   $pAPIServerURL = '', 
                   $pDebugLevel = 0, 
                   $pDebugSections = '', 
                   $pRequestAPIVersion = '') {
                     
                    
    if (! empty($pDebugLevel)) {
      $m_fields['DebugLevel'] = $pDebugLevel;
    } else {    
      $m_fields['DebugLevel'] = $this->DebugLevel;
    }
    

    if (! empty($pDebugSections)) {
        $m_fields['DebugSection'] = $pDebugSections;
    } else {    
        $m_fields['DebugSection'] = $this->DebugSections;
    }
    
    if (! empty($pRequestAPIVersion)) {
        $m_fields['APIVersion'] = $pRequestAPIVersion;
    } else {
        $m_fields['APIVersion'] = $this->RequestAPIVersion;
    };
    
//print_r ($pQuery);

    $mQueryType = gettype ($pQuery);
    
//echo $mQueryType;
        
    $m_fields['json'] ='';        
        
    switch ($mQueryType) {
        case 'string':
            $m_fields['json'] = $pQuery;
            break;
        case 'object':
        
            $pQuery->Prepare();
            $m_fields['json'] = $pQuery->toString();

            break;
            
        case 'array':
            $m_fields['json'] = json_encode($pQuery);
            break;
            
        default:
            throw new Exception('Query value of unsupported type: ' . $mQueryType);
            
    }
    
//echo "<br>";
//echo $m_fields['json'];    
        
    $this->LastQueryString = $m_fields['json'];
    
    if ($this->SaveRequestJSONToFile) {
      file_put_contents ('LastQueryString.json', $this->LastQueryString);
    }

    
 
		// pripremi CURL konekciju
		$m_session = curl_init();

		// ukljuci GZIP kompresiju 
		curl_setopt($m_session, CURLOPT_ENCODING, "gzip");
		curl_setopt($m_session, CURLOPT_RETURNTRANSFER, 1); 

		// ipsostuj redirekciju ako dobijes instrukciju od servera
		curl_setopt($m_session, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($m_session, CURLOPT_CUSTOMREQUEST, "POST");
		curl_setopt($m_session, CURLOPT_POSTREDIR, 3);

		// podesi URL APi servera
		curl_setopt($m_session, CURLOPT_URL, $this->APIServerURL);
		
		// podesi broj polja u POST upitu
		curl_setopt($m_session, CURLOPT_POST, count ($m_fields));
		
		// konvertuj polja upita u HTTP oblik
		$m_fields_query = http_build_query ($m_fields);
		
		// podesi upit
		curl_setopt($m_session, CURLOPT_POSTFIELDS, $m_fields_query);
		
		// podesi upit
		curl_setopt($m_session, CURLOPT_RETURNTRANSFER, true);
		
		// izvrsi upit i preuzmi rezultat
		$this->LastResponseString = curl_exec($m_session);
		
		$this->ContentType = curl_getinfo ($m_session, CURLINFO_CONTENT_TYPE);

		if ( $this->LastResponseString === false ) {
          echo "Error connecting to API server: $this->APIServerURL ";    
          echo "<br>";    
		}		
		
		// zatvori konekciju
		curl_close($m_session);

//echo $this->ContentType;
		
		if (strpos($this->ContentType, 'json') !== false) {
//echo "1 ";      
			$m_response = $this->GetResponse();
		} else {
//echo "2 ";            
			$m_response = $this->LastResponseString;
		}
    
//echo "<pre>!!!";
//$this->LastResponseString;
//echo "<pre>...";
//print_r ($m_response);
//echo "</pre>$$$";
      
      return $m_response;
    
  }
  
  function GetResponse() {
    
//$mResponseFileName = dirname(__FILE__) . '/resp-' . DATE ("Ymd-His") . '.json';
//file_put_contents ($mResponseFileName, $this->LastResponseString);
    
    
    //$m_response = json_decode ($this->LastResponseString);
    
    $m_response = new iapiResponseEnvelope ($this->LastResponseString);
    
    $m_json_error = json_last_error();
    if ($m_json_error <> JSON_ERROR_NONE) {
      echo "JSON decoding error: $m_json_error ";    
      echo $this->json_error_to_msg ($m_json_error);
      echo "<br>";    
    }
    
//echo "<pre>!!!";
//$this->LastResponseString;
//print_r ($m_response);
//echo "</pre>$$$";    
    
    
    if (isset ($m_response->data)) {
      $m_response->data = json_decode ($m_response->data);

    }
    
    if ( isset ($m_response->data->databaseattachment) && ($m_response->data->database_format == 'PLAIN_OBJ')) {

//echo "<pre>";
//print_r ($m_response->data->databaseattachment);
//echo "</pre>";


			if (! is_object ($m_response->data->databaseattachment)) {
            	$m_response->data->databaseattachment = json_decode ($m_response->data->databaseattachment);

				$m_json_error = json_last_error();

				if ($m_json_error <> JSON_ERROR_NONE) {
					echo "Database attachment JSON decode error: ";
          echo $this->json_error_to_msg ($m_json_error);

        }
      }
    }
    
//echo "<pre>";
//print_r ($m_response);
//echo "</pre>";

    $m_result = $m_response;
    
    return $m_result;
  }
  
  function GetContentType() {
	  return $this->ContentType;
  }

  function GetContent() {
	  return $this->LastResponseString;
  }

  
  
  function json_error_to_msg ($pError) {
      $m_json_error = $pError;
      
      $mResult = '';

				if ($m_json_error <> JSON_ERROR_NONE) {

          switch ($m_json_error) {
            case JSON_ERROR_NONE:
                $mResult = 'No errors';
            break;
            case JSON_ERROR_DEPTH:
                $mResult = 'Maximum stack depth exceeded';
            break;
            case JSON_ERROR_STATE_MISMATCH:
                $mResult = 'Underflow or the modes mismatch';
            break;
            case JSON_ERROR_CTRL_CHAR:
                $mResult = 'Unexpected control character found';
            break;
            case JSON_ERROR_SYNTAX:
                $mResult = 'Syntax error, malformed JSON';
            break;
            case JSON_ERROR_UTF8:
                $mResult = 'Malformed UTF-8 characters, possibly incorrectly encoded';
            break;
            default:
                $mResult = 'Unknown error';
            break;
          }

        }  
      return $mResult;
  }
}
?>