<?php namespace JsonApi\Data;

class DataItem implements \JsonSerializable {

	/** @var string The resource type which this data represents. **/
	protected $type;

	/** @var string The unique ID of the resource. **/
	protected $id;

	/** @var string The attributes of the resource. **/
	protected $attributes = [];

	/** @var string The relationships of this resource. **/
	protected $relationships = [];

	/**
	 * Initialize the data item.
	 *
	 * @param	string The resource type which this data represents.
	 * @param	string The unique ID of the resource.
	 * @param	string The attributes of the resource.
	 * @param	string The relationships of this resource.
	 */
	public function __construct($type, $id = null, $attributes = [], $relationships = []) {
		$this->id = $id . '';
		$this->type = $type;
		$this->attributes = $attributes;
		$this->relationships = $relationships;
	}

	/**
	 * Initialize the data item from the JSON data.
	 *
	 * @param	object	$data	The JSON data to read from.
	 */
	public static function parse($data) {

		# Mandatory: type
		if(empty($data['type'])) {
			throw new \Exception('DataItem must have `type` parameter.');
		}

		return new self(
			$data['type'],
			key_exists('id', $data) ? $data['id'] : null,
			key_exists('attributes', $data) ? $data['attributes'] : null,
			key_exists('relationships', $data) ? $data['relationships'] : null
		);
	}

	/**
	 * Set an atrribute to the data.
	 *
	 * @param	$name	The name of the attribute.
	 * @param	$value	The value of the attribute.
	 *
	 * @return	DataItem	Itself, for chaining.
	 */
	public function setAttribute($name, $value) {
		$this->attributes[$name] = $value;
		return $this;
	}

	/**
	 * Get the attribute from the data.
	 *
	 * @param	string	$name	The name of the attribute.
	 *
	 * @return	mixed	The attribute for the supplied name.
	 */
	public function getAttribute($name) {

		# Validate
		if(!key_exists($name, $this->attributes)) {
			throw new Exception("Data does not have the attribute `{$name}`.");
		}

		return $this->attributes[$name];
	}

	public function getId() { return $this->id; }
	public function getType() { return $this->type; }
	public function getAttributes() { return $this->attributes; }

	public function jsonSerialize() {
		$json = [];
		$json['type'] = $this->type;
		$this->optional($json, 'id');
		$this->optional($json, 'attributes');
		$this->optional($json, 'relationships');

		return $json;
	}

	private function optional(&$json, $key) { if(isset($this->$key) && $this->$key !== null) $json[$key] = $this->$key; }

}
