<?php defined('SYSPATH') OR die('No direct access allowed.');

/**
 * OAuth Provider
 *
 * @package    Kohana/OAuth2
 * @author     Deon George
 * @copyright  (c) 2009-2013 Deon George
 * @license    http://dev.leenooks.net/license.html
 */
abstract class Kohana_OAuth2_Provider {
	private $response;

	public static function factory($name, array $options = NULL)
	{
		$class = 'OAuth2_Provider_'.ucfirst($name);

		return new $class($options);
	}

	/**
	 * Return the value of any protected class variable.
	 *
	 *     // Get the provider signature
	 *     $signature = $provider->signature;
	 *
	 * @param   string  variable name
	 * @return  mixed
	 */
	public function __get($key)
	{
		return $this->$key;
	}

	abstract public function url_authorize();

	abstract public function url_access_token();

	public $name;

	protected $scope;

	public function url_refresh_token()
	{
		// By default its the same as access token URL
		return $this->url_access_token();
	}

	public function authorize_url(OAuth2_Client $client, array $params = NULL)
	{
		// Create a new GET request for a request token with the required parameters
		$request = OAuth2_Request::factory('authorize', 'GET', $this->url_authorize(), array(
			'response_type' => 'code',
			'client_id'     => $client->id,
			'redirect_uri'  => $client->callback,
			'scope'         => $this->scope,
		));

		if ($params)
		{
			// Load user parameters
			$request->params($params);
		}

		return $request->as_url();
	}

	public function access_token(OAuth2_Client $client, $code, array $params = NULL)
	{
		$request = OAuth2_Request::factory('token', 'POST', $this->url_access_token(), array(
			'grant_type'    => 'authorization_code',
			'code'          => $code,
			'client_id'     => $client->id,
			'client_secret' => $client->secret,
		));

		if ($client->callback)
		{
			$request->param('redirect_uri', $client->callback);
		}

		if ($params)
		{
			// Load user parameters
			$request->params($params);
		}

		$response = $request->execute();

		return OAuth2_Token::factory('access', array(
			'token' => $response->param('access_token')
		));
	}

	public function user_details(OAuth2_Client $client, array $params = NULL) {
		$request = OAuth2_Request::factory('resource', 'GET', $this->url_user_details(), array(
		));

		if ($params)
		{
			// Load user parameters
			$request->params($params);
		}

		// Create a response from the request
		$response = $request->execute();

		// Store these user details useful
		return OAuth2_API::factory($this, 'profile', array(
			'provider' => $this->name,
			'profile'  => json_decode($response),
		));
	}

	/**
	 * Execute an OAuth2 request, apply any provider-specfic options to the request.
	 *
	 * @param   object  request object
	 * @param   array   request options
	 * @return  mixed
	 */
	public function execute(OAuth2_Request $request, array $options = NULL)
	{
		return $request->execute($options);
	}

}
