<?php

declare(strict_types=1);

namespace CpCreation\AltchaBundle\Tests\Double;

use CpCreation\AltchaBundle\Contract\AltchaServiceClientInterface;
use CpCreation\AltchaBundle\Model\Challenge;
use CpCreation\AltchaBundle\Model\ScopeManifest;
use CpCreation\AltchaBundle\Model\ScopePolicy;
use CpCreation\AltchaBundle\Model\ScopeSyncResult;
use CpCreation\AltchaBundle\Model\VerificationRequest;
use CpCreation\AltchaBundle\Model\VerificationResult;

final class FakeAltchaServiceClient implements AltchaServiceClientInterface
{
    public ScopePolicy|\Throwable $policy;

    public VerificationResult|\Throwable $verification;

    /** @var list<VerificationRequest> */
    public array $verificationRequests = [];

    /** @var list<array{scope: string, host: string, clientIp: string, formToken: string, policyVersion: int}> */
    public array $challengeRequests = [];

    /** @var list<array{scope: string, host: string}> */
    public array $policyRequests = [];

    public function __construct()
    {
        $this->policy = new ScopePolicy(
            scope: 'site.contact',
            enabled: true,
            version: 7,
            altchaEnabled: true,
            profile: 'pbkdf2-default',
            minimumFillTimeMs: 0,
            maximumEnvelopeAgeSeconds: 900,
            subjectLimitsEnabled: false,
        );
        $this->verification = new VerificationResult(true);
    }

    public function resolvePolicy(string $scope, string $host): ScopePolicy
    {
        $this->policyRequests[] = compact('scope', 'host');
        if ($this->policy instanceof \Throwable) {
            throw $this->policy;
        }

        return $this->policy;
    }

    public function createChallenge(string $scope, string $host, string $clientIp, string $formToken, int $policyVersion): Challenge
    {
        $this->challengeRequests[] = compact('scope', 'host', 'clientIp', 'formToken', 'policyVersion');

        return new Challenge(['algorithm' => 'PBKDF2', 'challenge' => 'abc'], 'signed');
    }

    public function verifyAndConsume(VerificationRequest $request): VerificationResult
    {
        $this->verificationRequests[] = $request;
        if ($this->verification instanceof \Throwable) {
            throw $this->verification;
        }

        return $this->verification;
    }

    public function synchronizeScopes(ScopeManifest $manifest, bool $dryRun): ScopeSyncResult
    {
        return new ScopeSyncResult($dryRun, ['site.contact'], [], []);
    }
}
