<?php

namespace Vinteract\API;

class Response {
	
	/*
		
		Properties
		
	*/
	
	private $headers = [];
	
	private $response = [];
	
	/*
		
		Constructor
		
	*/
	
	function __construct($params = null) {
		
		// No params?
		
		if ($params == null) {
			$params = [];
		}
		
		// Variables.
		
		$code = array_key_exists("code", $params) ? $params["code"] : 400;
		$contents = array_key_exists("contents", $params) ? $params["contents"] : [];
		$message = array_key_exists("message", $params) ? $params["message"] : null;
		$results = array_key_exists("results", $params) ? $params["results"] : null;
		
		// Headers.
		
		$this->headers = array_key_exists("headers", $params) ? $params["headers"] : [];
		
		// Response.
		
		$this->response = [
			"code" => $code,
		];
		
		// Response message?
		
		if ($message !== null) {
			
			$this->response["message"] = $message;
			
		} else {
			
			$messages = [
				200 => "Success.",
				201 => "Successfully created.",
				400 => "There is an issue with your request.",
				401 => "You are not authorized to make this request.",
				403 => "Forbidden request.",
				404 => "No results.",
				500 => "Internal server error.",
			];
			
			if (array_key_exists($code, $messages)) {
				$this->response["message"] = $messages[$code];
			}
			
		}
		
		// Success or error?
		
		if ($code == 200 or $code == 201) {
			$this->response["success"] = true;
		} else {
			$this->response["error"] = true;
		}
		
		// Results?
		
		if (isset($results) and count($results)) {
			$this->response["results"] = $results;
		}
		
		// Custom contents.
		
		foreach($contents as $key => $var) {
			$this->response[$key] = $var;
		}
		
	}
	
	/*
		
		Destructor
		
	*/
	
	function __destruct() {
		
	}
	
	/*
		
		Methods
		
	*/
	
	public function success() {
		if (array_key_exists("success", $this->response)) {
			return $this->response["success"] === true;
		}
		return false;
	}
	
	public function error() {
		if (array_key_exists("error", $this->response)) {
			return $this->response["error"] === true;
		}
		return false;
	}
	
	public function getResponseObject() {
		return $this->response;
	}
	
	public function echoResponse() {
		
		// Set any custom headers.
		
		foreach($this->headers as $key => $value) {
			header("{$key}: {$value}");
		}
		
		// Content type header.
		
		header("Content-Type: application/json");
		
		// HTTP response code.
		
		http_response_code($this->response["code"]);
		
		// Echo json.
		
		echo json_encode($this->response, JSON_NUMERIC_CHECK);
		
		exit();
		
	}
	
	/*
		
		Getters
		
	*/
	
	public function getCode() {
		return $this->response["code"];
	}
	
	public function getMessage() {
		return $this->response["message"];
	}
	
	public function getValue($key, $default = null) {
		
		// Variables
		
		$data = $this->response;
		
		// @assert $key is a non-empty string
		// @assert $data is a loopable array
		// @otherwise return $default value
		
		if (!is_string($key) || empty($key) || !count($data)) {
			return $default;
		}
		
		// @assert $key contains a dot notated string
		
		if (strpos($key, '.') !== false) {
			$keys = explode('.', $key);
			foreach ($keys as $innerKey) {
				// @assert $data[$innerKey] is available to continue
				// @otherwise return $default value
				if (!array_key_exists($innerKey, $data)) {
					return $default;
				}
				$data = $data[$innerKey];
			}
			return $data;
		}
		
		return array_key_exists($key, $data) ? $data[$key] : $default;
		
	}
	
	/*
		
		Setters
		
	*/
	
	public function setCode($code) {
		$this->response["code"] = $code;
		$this->response["success"] = ($code === 200 or $code === 201);
		$this->response["error"] = !$this->response["success"];
	}
	
	public function setMessage($message) {
		$this->response["message"] = $message;
	}
	
	public function setContents($contents = []) {
		foreach($contents as $key => $var) {
			$this->response[$key] = $var;
		}
	}
	
}
