<?php namespace Intellex\Curly;

use Intellex\Curly\Exception\MethodNotSupportedException;

/**
 * The list of all available methods.
 */
class Method {

	/** @const string The GET method requests a representation of the specified resource. Requests using GET should only retrieve data. */
	const GET = "GET";

	/** @const string The HEAD method asks for a response identical to that of a GET request, but without the response body. */
	const HEAD = "HEAD";

	/** @const string The POST method is used to submit an entity to the specified resource, often causing a change in state or side effects on the server. */
	const POST = "POST";

	/** @const string The PUT method replaces all current representations of the target resource with the request payload. */
	const PUT = "PUT";

	/** @const string The DELETE method deletes the specified resource. */
	const DELETE = "DELETE";

	/** @const string The CONNECT method establishes a tunnel to the server identified by the target resource. */
	const CONNECT = "CONNECT";

	/** @const string The OPTIONS method is used to describe the communication options for the target resource. */
	const OPTIONS = "OPTIONS";

	/** @const string The PATCH method is used to apply partial modifications to a resource. */
	const PATCH = "PATCH";

	/**
	 * The method itself.
	 */
	private $method;

	/**
	 * Initialize the method.
	 *
	 * @param string $method The requested method.
	 *
	 * @throws MethodNotSupportedException On method not recognized or not supported.
	 */
	public function __construct($method) {
		$this->method = static::validate($method);
	}

	/**
	 * Validate the string representation of a method.
	 *
	 * @param string $method The requested method.
	 *
	 * @return string The filtered method.
	 * @throws    MethodNotSupportedException On method not recognized or not supported.
	 */
	public static function validate($method) {
		$upper = strtoupper(trim($method));
		$supported = [ static::GET, static::HEAD, static::POST, static::PUT, static::DELETE, static::CONNECT, static::OPTIONS, static::PATCH ];
		foreach ($supported as $const) {
			if ($const === $upper) {
				return $const;
			}
		}

		throw new MethodNotSupportedException($method);
	}

	/**
	 * Convert the HTTP method to a string representation.
	 *
	 * @return string The string representation of the current HTTP method.
	 */
	public function toString() {
		return $this->method;
	}

}
