<?php

abstract class HybridAuthConnector extends AbstractProviderConnector
{

    abstract protected function getAccessTokenKey($provider);

    abstract protected function getRefreshTokenKey($provider);

    public function confirmCredential($model)
    {
        if ($model->save()) {
            Log::v("Created new ThirdPartyCredential model.", get_class($this));
            $this->redirect(
                    $this->createUrl(
                            '/phonesettingsThirdPartyCredentials/default/confirmCredential', array(
                        'id' => $model->id,
                        'provider' => $model->provider
                            )
                    )
            );
        } else {
            $this->onSaveError($model);
        }
    }

    public function setSessionData($haComp, $model)
    {
        $sessionData = $this->getSessionData($haComp, $model->provider);
        $this->updateThirdPartyCredentialsModel($model, $sessionData);
        if ($model->save()) {
            $haComp->hybridAuth->logoutAllProviders();
            $this->redirect($this->createUrl('/phonesettingsThirdPartyCredentials/default/index'));
        } else {
            $this->onSaveError($model);
        }
    }

    protected function onSaveError($model)
    {
        $this->createErrorLogMessages($model);
        throw new CHttpException(500, "Can not save ThirdPartyCredential model. " . get_class($this));
    }

    protected function getSessionData($haComp, $provider)
    {
        $rawSession = $haComp->hybridAuth->getSessionData();
        $session = unserialize($rawSession);

        $accessTokenKey = $this->getAccessTokenKey($provider);
        $tokenSecretKey = $this->getRefreshTokenKey($provider);

        $sessionToken = isset($session[$accessTokenKey]) ? unserialize($session[$accessTokenKey]) : "";
        $sessionSecret = isset($session[$tokenSecretKey]) ? unserialize($session[$tokenSecretKey]) : "";

        return array('rawSessionData' => $rawSession, 'sessionToken' => $sessionToken, 'sessionSecret' => $sessionSecret);
    }

    protected function updateThirdPartyCredentialsModel($model, $sessionData)
    {

        $model->authenticated = ThirdPartyCredentialStatus::authenticated;
        $model->passwordStatus = ThirdPartyCredentialStatus::valid;
        $model->hauthSession = $sessionData['rawSessionData'];
        $model->token = $sessionData['sessionToken'];
        $model->secret = $sessionData['sessionSecret'];
        $model->updated = time();
    }

    protected function gatherMetaDataForSyncJob($model)
    {
        try {
            $auth = new HybridAuthAdapter($model->provider);
            $this->getAuthAdapter($auth, $model);
            $this->createSyncJob($model->id, $auth->adapter->getTotalContactCount());
        } catch (Exception $exception) {
            $model->passwordStatus = ThirdPartyCredentialStatus::invalid;
            if (!$model->save()) {
                $this->createErrorLogMessages($model);
            }
        }
    }

    protected function getAuthAdapter($auth, $model)
    {
        $auth->hybridAuth->logoutAllProviders();
        $auth->hybridAuth->restoreSessionData($model->hauthSession);
        $auth->adapter = $auth->hybridAuth->authenticate($model->provider);
    }
}
