<commit_before><?php
namespace Jmondi\Restforce;

use GuzzleHttp\Client as GuzzleClient;
use Jmondi\Restforce\Token\TokenRefreshCallbackInterface;
use Psr\Http\Message\ResponseInterface;
use Stevenmaguire\OAuth2\Client\Provider\Salesforce as SalesforceProvider;
use Stevenmaguire\OAuth2\Client\Token\AccessToken;

class SalesforceProviderRestClient implements RestClientInterface
{
    /**
     * @var GuzzleClient
     */
    private $client;
    /**
     * @var SalesforceProvider
     */
    private $salesforceProvider;
    /**
     * @var AccessToken
     */
    private $accessToken;
    /**
     * @var TokenRefreshCallbackInterface|null
     */
    private $tokenRefreshCallback;
    /**
     * @var int
     */
    private $maxRetry;

    public function __construct(
        RestClientInterface $client,
        SalesforceProvider $salesforceProvider,
        AccessToken $accessToken,
        TokenRefreshCallbackInterface $tokenRefreshCallback = null,
        int $maxRetry = 2
    )
    {
        $this->client = $client;
        $this->salesforceProvider = $salesforceProvider;
        $this->accessToken = $accessToken;
        $this->tokenRefreshCallback = $tokenRefreshCallback;
        $this->maxRetry = $maxRetry;
    }

    public function request(string $method, string $uri = '', array $options = []):ResponseInterface
    {
        return $this->retryRequest(
            $method,
            $uri,
            $this->mergeOptions($options)
        );
    }

    private function getAccessToken()
    {
        return $this->accessToken->getToken();
    }

    private function isResponseAuthorized(ResponseInterface $response):bool
    {
        if ($response->getStatusCode() === 401) {
            return false;
        } else {
            return true;
        }
    }

    private function refreshAccessToken():void
    {
        $accessToken = $this->salesforceProvider->getAccessToken('refresh_token', [
            'refresh_token' => $this->accessToken->getRefreshToken()
        ]);

        if (!empty($this->tokenRefreshCallback)) {
            $this->tokenRefreshCallback->tokenRefreshCallback($accessToken);
        }

        $this->accessToken = $accessToken;
    }

    private function mergeOptions(array $options):array
    {
        $defaultOptions = [
            'headers' => [
                'Authorization' => 'Bearer ' . $this->getAccessToken()
            ]
        ];
        $options = array_merge_recursive($defaultOptions, $options);
        return $options;
    }

    private function retryRequest(string $method, string $uri, array $options):ResponseInterface
    {
        $attempts = 0;<commit_msg>Temp die refresh access token to validate.<commit_after><?php
namespace Jmondi\Restforce;

use GuzzleHttp\Client as GuzzleClient;
use Jmondi\Restforce\Token\TokenRefreshCallbackInterface;
use Psr\Http\Message\ResponseInterface;
use Stevenmaguire\OAuth2\Client\Provider\Salesforce as SalesforceProvider;
use Stevenmaguire\OAuth2\Client\Token\AccessToken;

class SalesforceProviderRestClient implements RestClientInterface
{
    /**
     * @var GuzzleClient
     */
    private $client;
    /**
     * @var SalesforceProvider
     */
    private $salesforceProvider;
    /**
     * @var AccessToken
     */
    private $accessToken;
    /**
     * @var TokenRefreshCallbackInterface|null
     */
    private $tokenRefreshCallback;
    /**
     * @var int
     */
    private $maxRetry;

    public function __construct(
        RestClientInterface $client,
        SalesforceProvider $salesforceProvider,
        AccessToken $accessToken,
        TokenRefreshCallbackInterface $tokenRefreshCallback = null,
        int $maxRetry = 2
    )
    {
        $this->client = $client;
        $this->salesforceProvider = $salesforceProvider;
        $this->accessToken = $accessToken;
        $this->tokenRefreshCallback = $tokenRefreshCallback;
        $this->maxRetry = $maxRetry;
    }

    public function request(string $method, string $uri = '', array $options = []):ResponseInterface
    {
        return $this->retryRequest(
            $method,
            $uri,
            $this->mergeOptions($options)
        );
    }

    private function getAccessToken()
    {
        return $this->accessToken->getToken();
    }

    private function isResponseAuthorized(ResponseInterface $response):bool
    {
        if ($response->getStatusCode() === 401) {
            return false;
        } else {
            return true;
        }
    }

    private function refreshAccessToken():void
    {
        var_dump('refresh access token!! Dying on this to verify access token temp');
        die();
        $accessToken = $this->salesforceProvider->getAccessToken('refresh_token', [
            'refresh_token' => $this->accessToken->getRefreshToken()
        ]);

        if (!empty($this->tokenRefreshCallback)) {
            $this->tokenRefreshCallback->tokenRefreshCallback($accessToken);
        }

        $this->accessToken = $accessToken;
    }

    private function mergeOptions(array $options):array
    {
        $defaultOptions = [
            'headers' => [
                'Authorization' => 'Bearer ' . $this->getAccessToken()
            ]
        ];
        $options = array_merge_recursive($defaultOptions, $options);
        return $options;
    }

    private function retryRequest(string $method, string $uri, array $options):ResponseInterface
    {
        $attempts = 0;
{'fraction_non_alphanumeric': 0.10933480338110989, 'fraction_numerical': 0.0025725836089672913, 'mean_word_length': 2.5025740025740024, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7133249', 'n_tokens_mistral': 1479, 'n_tokens_neox': 1439, 'n_words': 283}