<?php
/*
 * Copyright (c) 2013, 2014 MasterCard International Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 * Neither the name of the MasterCard International Incorporated nor the names of its
 * contributors may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/**
 * AccessToken - used to manage OAuth access tokens
 */
class Simplify_AccessToken extends Simplify_Object {

    public function __construct($hash) {
        $this->setAll($hash);
    }

    /**
     * Creates an OAuth access token
     * @param $code - the authorisation code returned from the GET on /oauth/authorize
     * @param $redirect_uri = this must be the redirect_uri set in the apps configuration
     * @param $authentication - Authentication information to access the API.  If not value is passed the global key Simplify::$publicKey and Simplify::$privateKey are used
     * @return Simplify_AccessToken
     */
    public static function create($code, $redirect_uri, $authentication = null) {

        $args = func_get_args();
        $authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 3);

        $props = 'code='.$code.'&redirect_uri='.$redirect_uri.'&grant_type=authorization_code';
        $resp = Simplify_AccessToken::sendRequest($props, "token", $authentication);

        return new Simplify_AccessToken($resp);
    }

    /**
     * Refreshes the current token.  The access_token and refresh_token values will be updated.
     * @param $authentication - Authentication information to access the API.  If not value is passed the global key Simplify::$publicKey and Simplify::$privateKey are used
     * @return Simplify_AccessToken
     * @throws InvalidArgumentException
     */
    public function refresh($authentication = null) {

        $refresh_token = $this->refresh_token;
        if (empty($refresh_token)){
            throw new InvalidArgumentException('Cannot refresh access token; refresh token is invalid');
        }

        $args = func_get_args();
        $authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);

        $props = 'refresh_token='.$refresh_token.'&grant_type=refresh_token';
        $resp = Simplify_AccessToken::sendRequest($props, "token", $authentication);

        $this->setAll($resp);

        return $this;
    }

    /**
     * <p>Revokes a token from further use.
     * @param $authentication - Authentication information to access the API.  If not value is passed the global key Simplify::$publicKey and Simplify::$privateKey are used
     * @return Simplify_AccessToken
     * @throws InvalidArgumentException
     */
    public function revoke($authentication = null) {

        $access_token = $this->access_token;
        if (empty($access_token)){
            throw new InvalidArgumentException('Cannot revoke access token; access token is invalid');
        }

        $args = func_get_args();
        $authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);

        $props = 'token='.$access_token.'';

        Simplify_AccessToken::sendRequest($props, "revoke", $authentication);

        $this->access_token = null;
        $this->refresh_token = null;
        $this->redirect_uri = null;

        return $this;
    }

    /**
     * @param string $props
     * @param string $context
     * @param Simplify_Authentication $authentication
     */
    private static function sendRequest($props, $context, $authentication){

        $url = Simplify_Constants::OAUTH_BASE_URL.'/'.$context;
        $http = new Simplify_HTTP();
        $resp = $http->oauthRequest($url, $props, $authentication);

        return $resp;
    }

    /**
     * @ignore
     */
    static public function getClazz() {
        return "AccessToken";
    }

}
