<?php

/**
    The authorization code is obtained by using an authorization server
    as an intermediary between the client and resource owner.  Instead of
    requesting authorization directly from the resource owner, the client
    directs the resource owner to an authorization server (via its
    user-agent as defined in [RFC2616]), which in turn directs the
    resource owner back to the client with the authorization code.

    Before directing the resource owner back to the client with the
    authorization code, the authorization server authenticates the
    resource owner and obtains authorization.  Because the resource owner
    only authenticates with the authorization server, the resource
    owner's credentials are never shared with the client.

    The authorization code provides a few important security benefits,
    such as the ability to authenticate the client, as well as the
    transmission of the access token directly to the client without
    passing it through the resource owner's user-agent and potentially
    exposing it to others, including the resource owner.

 * Flow:
 *
 * 1.) Make an Authorization request
 * 2.) Server replies with Authorization response
 * 3.) Make an Access Token request
 * 4.) Server replies with Access Token Response
 *
 */

namespace AuthStack\OAuth2\Model\Protocol\Grant;

use Illuminate\Http\Request;
use AuthStack\OAuth2\Model\Protocol\Request\AuthorizationCode\{AuthorizationRequest, TokenRequest};
use AuthStack\OAuth2\Model\Protocol\Response\AuthorizationCode\{AuthorizationResponse, TokenResponse};

class AuthorizationCode implements GrantInterface
{
    /**
     * @param array $model
     * @return AuthorizationRequest
     */
    public function authorizationRequest(array $model = []): AuthorizationRequest
    {
        $result = new AuthorizationRequest();

        return !empty($model) ? $result->setModel($model) : $result;
    }

    /**
     * @param Request|null $request
     * @return AuthorizationResponse
     */
    public function authorizationResponse(Request $request = null): AuthorizationResponse
    {
        $response = new AuthorizationResponse();

        $request = $request ?? Request::createFromGlobals();

        if($request->has('state')) $response->setState($request->input('state'));

        return $response;
    }

    /**
     * @return TokenRequest
     */
    public function tokenRequest(): TokenRequest
    {
        return new TokenRequest();
    }

    /**
     * @return TokenResponse
     */
    public function tokenResponse(): TokenResponse
    {
        return new TokenResponse();
    }
}