<?php

declare(strict_types=1);

final class MyronMcpConnectorAuthAdapter implements MyronApiAuthMethod
{
    public function __construct(
        private readonly MyronMcpOAuthTokenService $tokenService,
        private readonly MyronAiIntegrationRepository $aiIntegrations,
    ) {
    }

    /**
     * @param array<string, string|null> $headers
     */
    public function resolveCaller(array $headers, bool $publicEndpoint): ?MyronActionCallerContext
    {
        $bearer = $this->extractBearer($headers);
        if ($bearer === null || !str_starts_with($bearer, MyronMcpOAuthTokenCodec::ACCESS_PREFIX)) {
            return null;
        }

        $token = $this->tokenService->resolveAccessToken($bearer);
        if ($token === null) {
            throw new MyronApiAuthError(
                'Authorization rejected: OAuth access token is invalid, expired, revoked, or not audience-bound to this MCP server.',
                httpStatus: 401,
                errorCode: 'auth_invalid'
            );
        }

        $integrationId = (string) ($token['integrationId'] ?? '');
        $integration = $this->aiIntegrations->findById($integrationId);
        if ($integration === null || $integration->isRevoked()) {
            throw new MyronApiAuthError(
                'Authorization rejected: OAuth connector grant is not active.',
                httpStatus: 401,
                errorCode: 'auth_invalid'
            );
        }

        $this->aiIntegrations->recordUse($integrationId);
        return new MyronActionCallerContext(
            callerType: 'ai-bearer',
            callerId: $integrationId,
            heldScopes: $integration->scopes,
        );
    }

    /**
     * @param array<string, string|null> $headers
     */
    private function extractBearer(array $headers): ?string
    {
        foreach ($headers as $name => $value) {
            if (
                strcasecmp((string) $name, 'Authorization') !== 0
                && strcasecmp((string) $name, 'HTTP_AUTHORIZATION') !== 0
                && strcasecmp((string) $name, 'REDIRECT_HTTP_AUTHORIZATION') !== 0
            ) {
                continue;
            }
            $raw = trim((string) $value);
            if (stripos($raw, 'bearer ') === 0) {
                return trim(substr($raw, 7));
            }
        }

        return null;
    }
}

