<?php
class EndpointController extends AppBackendController {

	# Load components
	public $components = array('Api');


# ~ Get the list of API methods	 - - - - - - - - - - - - - - - - - - - - - - - #
	public function get_init() {

		# Get the array of methods and their groups
		// $groups = $this->model('Method')->getMethods();

		# Send the response
		$this->send(compact('groups'));
	}


# ~ Configuration  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	public function GET_configuration() { return $this->GET_('Configuration'); }
	public function POST_configuration() { return $this->POST_('Configuration'); }


# ~ Header variables - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	public function GET_header() { return $this->GET_('Header'); }
	public function POST_header() { return $this->POST_('Header'); }


# ~ Environment variables  - - - - - - - - - - - - - - - - - - - - - - - - - - #
	public function GET_environment() { return $this->GET_('Environment'); }
	public function POST_environment() { return $this->POST_('Environment'); }


# ~ Defined functions  - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	public function GET_function() { return $this->GET_('APIFunction'); }
	public function POST_function() { return $this->POST_('APIFunction'); }


# ~ Collections of functions - - - - - - - - - - - - - - - - - - - - - - - - - #
	public function GET_collection() { return $this->GET_('FunctionCollection'); }
	public function POST_collection() { return $this->POST_('FunctionCollection'); }


# ~ Get the data for the model - - - - - - - - - - - - - - - - - - - - - - - - #
	private function GET_($model) {

		# Get and send data
		$data = $this->model($model)->get();
		$this->send($data);
	}


# ~ Update the model - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	private function POST_($model) {

		# Get and save data
		$success = $this->model($model)->update($this->request->data);
		$this->send($success);
	}


# ~ The main entry of the endpoint - - - - - - - - - - - - - - - - - - - - - - #
	public function router() {
		try {

			# Get the parameters
			$this->request->data = @json_decode(file_get_contents("php://input"), true);

			# Get the request
			$request = strtoupper($this->request->method());
			$method = $this->request->params['method'];
			$target = "{$request}_{$method}";

			# Validate the request
			try {
				$targetInfo = new ReflectionMethod($this, $target);

				if($targetInfo->class !== get_class($this) || !$targetInfo->isPublic()) {
					throw new Exception();
				}

			} catch(Exception $ex) {
				throw new APIHardException(404, 'Unknown API function called');
			}

			# Invoke
			call_user_func_array(array($this, $target), $this->request->params['pass']);

			# If this is reached, something went bad
			throw new APIHardException(500, 'Overdrive exception');

		} catch(Exception $ex) {
			$this->handleException($ex);
		}
	}


# ~ Initialize the model from class registry - - - - - - - - - - - - - - - - - #
	protected static function model($modelName) {
		return ClassRegistry::init('WatchDog.' . $modelName);
	}


# ~ Send the response to the client	 - - - - - - - - - - - - - - - - - - - - - #
	private function send($data) {

		# Success response
		if(is_bool($data)) {
			$data = array(
				'success' => $data
			);
		}

		# Send response
		$this->Api->build(null, $data, false);
	}


# ~ Handle the received exception  - - - - - - - - - - - - - - - - - - - - - - #
	private function handleException($ex) {

		# Soft exception
		if($ex instanceof APISoftException) {
			$this->build($ex->wrapper, array(
				'success' => false,
				'message' => $ex->text,
			) + (array)$ex->additional);

			return;
		}

		# Hard exception
		if($ex instanceof APIHardException) {
			$code = $ex->code;
			$error = $ex->text;

		# Unknown exception
		} else {
			$code = 500;
			$error = $ex->getMessage();
		}

		# Return response
		$this->Api->build($code, $error);
	}

}
