<?php

/*
 * This file is part of the official PHP MCP SDK.
 *
 * A collaboration between Symfony and the PHP Foundation.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace Matomo\Dependencies\McpServer\Mcp\Server\Transport\Http\OAuth;

/**
 * Describes the outcome of an authorization decision.
 *
 * Use the static factory methods to create instances:
 * - allow() - Access is granted
 * - unauthorized() - No valid credentials provided (401)
 * - forbidden() - Valid credentials but insufficient permissions (403)
 * - badRequest() - Malformed request (400)
 *
 * @author Volodymyr Panivko <sveneld300@gmail.com>
 */
final class AuthorizationResult
{
    /**
     * @param list<string>|null    $scopes     Scopes to include in WWW-Authenticate challenge
     * @param array<string, mixed> $attributes Attributes to attach to the request on success
     */
    private function __construct(private readonly bool $allowed, private readonly int $statusCode, private readonly ?string $error, private readonly ?string $errorDescription, private readonly ?array $scopes, private readonly array $attributes)
    {
    }
    /**
     * Creates a result indicating access is allowed.
     *
     * @param array<string, mixed> $attributes Attributes to attach to the request (e.g., user_id, scopes)
     */
    public static function allow(array $attributes = []) : self
    {
        return new self(\true, 200, null, null, null, $attributes);
    }
    /**
     * Creates a result indicating the request is unauthorized (401).
     *
     * Use when no valid credentials are provided or the token is invalid.
     *
     * @param string|null       $error            OAuth error code (e.g., "invalid_token")
     * @param string|null       $errorDescription Human-readable error description
     * @param list<string>|null $scopes           Required scopes to include in challenge
     */
    public static function unauthorized(?string $error = null, ?string $errorDescription = null, ?array $scopes = null) : self
    {
        return new self(\false, 401, $error, $errorDescription, $scopes, []);
    }
    /**
     * Creates a result indicating the request is forbidden (403).
     *
     * Use when the token is valid but lacks required permissions/scopes.
     *
     * @param string|null       $error            OAuth error code (defaults to "insufficient_scope")
     * @param string|null       $errorDescription Human-readable error description
     * @param list<string>|null $scopes           Required scopes to include in challenge
     */
    public static function forbidden(?string $error = 'insufficient_scope', ?string $errorDescription = null, ?array $scopes = null) : self
    {
        return new self(\false, 403, $error ?? 'insufficient_scope', $errorDescription, $scopes, []);
    }
    /**
     * Creates a result indicating a bad request (400).
     *
     * Use when the Authorization header is malformed.
     *
     * @param string|null $error            OAuth error code (defaults to "invalid_request")
     * @param string|null $errorDescription Human-readable error description
     */
    public static function badRequest(?string $error = 'invalid_request', ?string $errorDescription = null) : self
    {
        return new self(\false, 400, $error ?? 'invalid_request', $errorDescription, null, []);
    }
    public function isAllowed() : bool
    {
        return $this->allowed;
    }
    public function getStatusCode() : int
    {
        return $this->statusCode;
    }
    public function getError() : ?string
    {
        return $this->error;
    }
    public function getErrorDescription() : ?string
    {
        return $this->errorDescription;
    }
    /**
     * @return list<string>|null
     */
    public function getScopes() : ?array
    {
        return $this->scopes;
    }
    /**
     * @return array<string, mixed>
     */
    public function getAttributes() : array
    {
        return $this->attributes;
    }
}
