<?php
namespace Engine\Mvc\Response\Components;

/**
 * The standard headers response
 * @author Lucian Sirbu
 */
class Headers
{
	/**
	 * Internal data
	 * @var array
	 */
	private $headers = [];


	/**
	 * Default status code
	 * @var int
	 */
	private $statusCode = 200;

	/**
	 * Internal json data
	 * @var \stdClass
	 */
	private $json = null;

	/**
	 * Create the headers response
	 * @param array $headers
	 */
	public function __construct($headers)
	{
		$this->headers = $headers;
	}

	/**
	 * Set the internal X-JSON object
	 * @param $json
	 * @return void
	 */
	public function setJson($json) :void
	{
		$this->json = $json;
	}

	/**
	 * Get the internal X-JSON object
	 * @return \stdClass
	 */
	public function getJson() :\stdClass
	{
		if ($this->json===null) {
			$this->json = new \stdClass();
		}

		return $this->json;
	}

	/**
	 * Set the repose status code
	 * @param int $statusCode
	 * @return void
	 */
	public function setStatusCode(int $statusCode) :void
	{
		$this->statusCode = $statusCode;
	}

	/**
	 * Get the response status code
	 * @return int
	 */
	public function getStatusCode() :int
	{
		return $this->statusCode;
	}

	/**
	 * Get the response status name
	 * @return string
	 */
	public function getStatusName() :string
	{
		switch ($this->statusCode) {
			case '200':
				return 'OK';
			break;
			case '404':
				return 'Not Found';
			break;
			case '500':
				return 'Internal Server Error';
			break;
		}

		return '';
	}

	/**
	 * Append to the internal headers list
	 * @param string $name
	 * @param string $value
	 * @return void
	 */
	public function append($name, $value) :void
	{
		$this->headers[] = sprintf("%s: %s", $name, $value);
	}

	/**
	 * Attach  messages to headers
	 * @param \App\MessagesCollector $msgs
	 * @return void
	 */
	public function loadMessages(\App\MessagesCollector $msgs) :void
	{
		$jsonMessages = $this->getJson();
		if (property_exists($jsonMessages, 'messages')) {
			$displayedMessages = (array)$jsonMessages->messages;
		} else {
			$displayedMessages = [];
		}
		foreach($msgs->getMessages() as $message) {
			$displayedMessages[] = ['type' => $message->getType(), 'message' => $message->getText()];
		}

		$jsonMessages->messages = $displayedMessages;
		$this->setJson($jsonMessages);
	}

	/**
	 * Get all headers
	 * @return array<string>
	 */
	public function getAll() :array
	{
		$headers = [];
		foreach ($this->headers as $header) {
			$headers[] = $header;
		}

		// TODO: in PHP 5.4 we could check if an objecty is empty by doing empty() or typecast to array, or typecast to bool
		// @see http://stackoverflow.com/questions/9412126/how-to-check-if-an-object-is-empty-in-php
		if ($this->json!==null && $this->json!=new \stdClass()) {
			$headers[] = sprintf("X-JSON: %s", json_encode((object)$this->json));
		}

		return $headers;
	}
}
