<commit_before><?php
namespace CloudFramework\Service\SocialNetworks\Connectors;

use CloudFramework\Patterns\Singleton;
use CloudFramework\Service\SocialNetworks\Exceptions\AuthenticationException;
use CloudFramework\Service\SocialNetworks\Exceptions\ConnectorConfigException;
use CloudFramework\Service\SocialNetworks\Exceptions\ConnectorServiceException;
use CloudFramework\Service\SocialNetworks\Exceptions\MalformedUrlException;
use CloudFramework\Service\SocialNetworks\Interfaces\SocialNetworkInterface;
use CloudFramework\Service\SocialNetworks\SocialNetworks;

/**
 * Class GoogleApi
 * @package CloudFramework\Service\SocialNetworks\Connectors
 * @author <NAME> <<EMAIL>>
 */
class GoogleApi extends Singleton implements SocialNetworkInterface {

    const ID = 'google';

    // Google client object
    private $client;

    // API keys
    private $clientId;
    private $clientSecret;
    private $clientScope = array();

    /**
     * Set Google Api keys
     * @param $clientId
     * @param $clientSecret
     * @param $clientScope
     * @throws ConnectorConfigException
     */
    public function setApiKeys($clientId, $clientSecret, $clientScope) {
        if ((null === $clientId) || ("" === $clientId)) {
            throw new ConnectorConfigException("'clientId' parameter is required");
        }

        if ((null === $clientSecret) || ("" === $clientSecret)) {
            throw new ConnectorConfigException("'clientSecret' parameter is required");
        }

        if ((null === $clientScope) || (!is_array($clientScope)) || (count($clientScope) == 0)) {
            throw new ConnectorConfigException("'clientScope' parameter is required");
        }

        $this->clientId = $clientId;
        $this->clientSecret = $clientSecret;
        $this->clientScope = $clientScope;

        $this->client = new \Google_Client();
        $this->client->setClassConfig("Google_Http_Request", "disable_gzip", true);
        $this->client->setClientId($this->clientId);
        $this->client->setClientSecret($this->clientSecret);
    }

    /**
     * Service that request authorization to Google making up the Google login URL
     * @param string $redirectUrl
     * @return array
     * @throws ConnectorConfigException
     * @throws MalformedUrlException
     */
    public function requestAuthorization($redirectUrl)
    {
        if ((null === $redirectUrl) || (empty($redirectUrl))) {
            throw new ConnectorConfigException("'redirectUrl' parameter is required");
        } else {
            if (!SocialNetworks::wellFormedUrl($redirectUrl)) {
                throw new MalformedUrlException("'redirectUrl' is malformed");
            }
        }

        $this->client->setRedirectUri($redirectUrl);
        $this->client->setAccessType("offline");
        foreach($this->clientScope as $scope) {
            $this->client->addScope($scope);
        }

        $authUrl = $this->client->createAuthUrl();

        if ((null === $authUrl) || (empty($authUrl))) {
            throw new ConnectorConfigException("'authUrl' parameter is required");
        } else {
            if (!SocialNetworks::wellFormedUrl($authUrl)) {
                throw new MalformedUrlException("'authUrl' is malformed");
            }
        }

        // Authentication request
        return $authUrl;
    }

    /**
     * Authentication service from google sign in request
     * @param string $code
     * @param string $redirectUrl
     * @return array
     * @throws AuthenticationException
     * @throws ConnectorException
     * @throws MalformedException
     * @throws \Exception
     *
     */
    public function authorize($code, $redirectUrl)
    {
        if ((null === $code) || ("" === $code)) {
            throw new ConnectorConfigException("'code' parameter is required");
        }

        if ((null === $redirectUrl) || (empty($redirectUrl))) {
            throw new ConnectorConfigException("'redirectUrl' parameter is required");
        } else {
            if (!SocialNetworks::wellFormedUrl($redirectUrl)) {
                throw new MalformedUrlException("'redirectUrl' is malformed");
            }
        }

        $this->client->setRedirectUri($redirectUrl);

        try {
            $this->client->authenticate($code);

            $googleCredentials = json_decode($this->client->getAccessToken(), true);
        } catch(\Exception $e) {
            if (401 === $e->getCode()) {
                throw new AuthenticationException("Error fetching OAuth2 access token, client is invalid");
            } else {
                throw new ConnectorServiceException($e->getMessage(), $e->getCode());
            }
        }

        return $googleCredentials;
    }

    /**
     * Method that inject the access token in google client
     * @param array $credentials
     */
    public function setAccessToken(array $credentials) {
        $this->client->setAccessToken(json_encode($credentials));
    }

    /**
     * Service that check if credentials are valid and authorized in google
     * @param array $credentials
     * @return mixed
     * @throws ConnectorConfigException
     * @throws ConnectorServiceException
     */
    public function checkCredentials(array $credentials) {
        $this->checkCredentialsParameters($credentials);

        try {
            $oauthService = new \Google_Service_Oauth2($this->client);
            $optParams["access_token"] = $credentials["access_token"];
            $optParams["id_token"] = $credentials["id_token"];
            $tokenInfo = $oauthService->tokeninfo($optParams);
        } catch (\Exception $e) {
            throw new ConnectorServiceException("The token has expired, has been tampered with, or the permissions revoked.");
        }

        return $tokenInfo;
    }

    /**
     * Service that refresh user's credentials and returns new ones
     * @param $credentials<commit_msg>ssh key gen in readme<commit_after><?php
namespace CloudFramework\Service\SocialNetworks\Connectors;

use CloudFramework\Patterns\Singleton;
use CloudFramework\Service\SocialNetworks\Exceptions\AuthenticationException;
use CloudFramework\Service\SocialNetworks\Exceptions\ConnectorConfigException;
use CloudFramework\Service\SocialNetworks\Exceptions\ConnectorServiceException;
use CloudFramework\Service\SocialNetworks\Exceptions\MalformedUrlException;
use CloudFramework\Service\SocialNetworks\Interfaces\SocialNetworkInterface;
use CloudFramework\Service\SocialNetworks\SocialNetworks;

/**
 * Class GoogleApi
 * @package CloudFramework\Service\SocialNetworks\Connectors
 * @author <NAME> <<EMAIL>>
 */
class GoogleApi extends Singleton implements SocialNetworkInterface {

    const ID = 'google';

    // Google client object
    private $client;

    // API keys
    private $clientId;
    private $clientSecret;
    private $clientScope = array();

    /**
     * Set Google Api keys
     * @param $clientId
     * @param $clientSecret
     * @param $clientScope
     * @throws ConnectorConfigException
     */
    public function setApiKeys($clientId, $clientSecret, $clientScope) {
        if ((null === $clientId) || ("" === $clientId)) {
            throw new ConnectorConfigException("'clientId' parameter is required");
        }

        if ((null === $clientSecret) || ("" === $clientSecret)) {
            throw new ConnectorConfigException("'clientSecret' parameter is required");
        }

        if ((null === $clientScope) || (!is_array($clientScope)) || (count($clientScope) == 0)) {
            throw new ConnectorConfigException("'clientScope' parameter is required");
        }

        $this->clientId = $clientId;
        $this->clientSecret = $clientSecret;
        $this->clientScope = $clientScope;

        $this->client = new \Google_Client();
        $this->client->setClassConfig("Google_Http_Request", "disable_gzip", true);
        $this->client->setClientId($this->clientId);
        $this->client->setClientSecret($this->clientSecret);
    }

    /**
     * Service that request authorization to Google making up the Google login URL
     * @param string $redirectUrl
     * @return array
     * @throws ConnectorConfigException
     * @throws MalformedUrlException
     */
    public function requestAuthorization($redirectUrl)
    {
        if ((null === $redirectUrl) || (empty($redirectUrl))) {
            throw new ConnectorConfigException("'redirectUrl' parameter is required");
        } else {
            if (!SocialNetworks::wellFormedUrl($redirectUrl)) {
                throw new MalformedUrlException("'redirectUrl' is malformed");
            }
        }

        $this->client->setRedirectUri($redirectUrl);
        $this->client->setAccessType("offline");
        foreach($this->clientScope as $scope) {
            $this->client->addScope($scope);
        }

        $authUrl = $this->client->createAuthUrl();

        if ((null === $authUrl) || (empty($authUrl))) {
            throw new ConnectorConfigException("'authUrl' parameter is required");
        } else {
            if (!SocialNetworks::wellFormedUrl($authUrl)) {
                throw new MalformedUrlException("'authUrl' is malformed");
            }
        }

        // Authentication request
        return $authUrl;
    }

    /**
     * Authentication service from google sign in request
     * @param string $code
     * @param string $redirectUrl
     * @return array
     * @throws AuthenticationException
     * @throws ConnectorException
     * @throws MalformedException
     * @throws \Exception
     *
     */
    public function authorize($code, $redirectUrl)
    {
        if ((null === $code) || ("" === $code)) {
            throw new ConnectorConfigException("'code' parameter is required");
        }

        if ((null === $redirectUrl) || (empty($redirectUrl))) {
            throw new ConnectorConfigException("'redirectUrl' parameter is required");
        } else {
            if (!SocialNetworks::wellFormedUrl($redirectUrl)) {
                throw new MalformedUrlException("'redirectUrl' is malformed");
            }
        }

        $this->client->setRedirectUri($redirectUrl);

        try {
            $this->client->authenticate($code);

            $googleCredentials = json_decode($this->client->getAccessToken(), true);
        } catch(\Exception $e) {
            if (401 === $e->getCode()) {
                throw new AuthenticationException("Error fetching OAuth2 access token, client is invalid");
            } else {
                throw new ConnectorServiceException($e->getMessage(), $e->getCode());
            }
        }

        return $googleCredentials;
    }

    /**
     * Method that inject the access token in google client
     * @param array $credentials
     */
    public function setAccessToken(array $credentials) {
        $this->client->setAccessToken(json_encode($credentials));

    }

    /**
     * Service that check if credentials are valid and authorized in google
     * @param array $credentials
     * @return mixed
     * @throws ConnectorConfigException
     * @throws ConnectorServiceException
     */
    public function checkCredentials(array $credentials) {
        $this->checkCredentialsParameters($credentials);

        try {
            $oauthService = new \Google_Service_Oauth2($this->client);
            $optParams["access_token"] = $credentials["access_token"];
            $optParams["id_token"] = $credentials["id_token"];
            $tokenInfo = $oauthService->tokeninfo($optParams);
        } catch (\Exception $e) {
            throw new ConnectorServiceException("The token has expired, has been tampered with, or the permissions revoked.");
        }

        return $tokenInfo;
    }

    /**
     * Service that refresh user's credentials and returns new ones
     * @param $credentials
{'fraction_non_alphanumeric': 0.11984765129073212, 'fraction_numerical': 0.0010156580617858655, 'mean_word_length': 2.758269720101781, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 79, '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': '491966', 'n_tokens_mistral': 3080, 'n_tokens_neox': 2993, 'n_words': 697}