<?php

namespace PragmaRX\Health\Checkers;

use DocuSign\eSign\Api\AuthenticationApi;
use DocuSign\eSign\Api\AuthenticationApi\LoginOptions;
use DocuSign\eSign\ApiClient;
use DocuSign\eSign\Configuration;
use DomainException;
use PragmaRX\Health\Support\Result;

class Docusign extends Base
{
    /**
     * @return Result
     */
    public function check()
    {
        if ($this->docusignIsNotInstalled()) {
            return $this->makeResult(false, $this->target->notInstalledMessage);
        }

        if (! $this->login()) {
            throw new DomainException(
                'Unable to authenticate to the DocuSign Api'
            );
        }

        return $this->makeHealthyResult();
    }

    private function docusignIsNotInstalled()
    {
        return ! class_exists(ApiClient::class);
    }

    private function getAccountIdFromLogin($login)
    {
        return $login->getLoginAccounts()[0]->getAccountId();
    }

    /**
     * @param  $config
     * @return ApiClient
     */
    protected function getApiClient($config)
    {
        return new ApiClient($config);
    }

    /**
     * @param  $config
     * @return AuthenticationApi
     */
    protected function getAuthApi($config)
    {
        return new AuthenticationApi($this->getApiClient($config));
    }

    /**
     * @return ApiClient
     */
    protected function getConfig()
    {
        return (new Configuration())
            ->setDebug($this->target->debug)
            ->setDebugFile($this->makeFileName($this->target->debugFile))
            ->setHost($this->target->apiHost)
            ->addDefaultHeader(
                'X-DocuSign-Authentication',
                json_encode([
                    'Username' => $this->target->username,
                    'Password' => $this->target->password,
                    'IntegratorKey' => $this->target->integratorKey,
                ])
            );
    }

    /**
     * @param  $config
     * @return \DocuSign\eSign\Model\LoginInformation
     */
    protected function getLoginInformation($config)
    {
        return $this->getAuthApi($config)->login($this->getLoginOptions());
    }

    /**
     * @return LoginOptions
     */
    protected function getLoginOptions()
    {
        return new LoginOptions();
    }

    /**
     * @return mixed
     */
    protected function login()
    {
        return $this->getAccountIdFromLogin(
            $this->getLoginInformation($this->getConfig())
        );
    }

    private function makeFileName($file)
    {
        if (is_absolute_path($file)) {
            return $file;
        }

        return base_path($file);
    }
}
