<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

use App\Framework\Exception\ErrorCode;

/**
 * MCP (Model Context Protocol) error codes
 *
 * Covers MCP server operations, tool execution, and protocol communication
 */
enum McpErrorCode: string implements ErrorCode
{
    case TOOL_NOT_FOUND = 'MCP001';
    case TOOL_EXECUTION_FAILED = 'MCP002';
    case INVALID_TOOL_ARGUMENTS = 'MCP003';
    case RESOURCE_NOT_FOUND = 'MCP004';
    case PROTOCOL_ERROR = 'MCP005';
    case SERVER_UNAVAILABLE = 'MCP006';

    public function getValue(): string
    {
        return $this->value;
    }

    public function getCategory(): string
    {
        return 'MCP';
    }

    public function getNumericCode(): int
    {
        return (int) substr($this->value, -3);
    }

    public function getSeverity(): ErrorSeverity
    {
        return match($this) {
            self::SERVER_UNAVAILABLE,
            self::PROTOCOL_ERROR => ErrorSeverity::CRITICAL,

            self::TOOL_EXECUTION_FAILED => ErrorSeverity::ERROR,

            self::TOOL_NOT_FOUND,
            self::INVALID_TOOL_ARGUMENTS,
            self::RESOURCE_NOT_FOUND => ErrorSeverity::WARNING,
        };
    }

    public function getDescription(): string
    {
        return match($this) {
            self::TOOL_NOT_FOUND => 'MCP tool not found',
            self::TOOL_EXECUTION_FAILED => 'MCP tool execution failed',
            self::INVALID_TOOL_ARGUMENTS => 'Invalid arguments provided to MCP tool',
            self::RESOURCE_NOT_FOUND => 'MCP resource not found',
            self::PROTOCOL_ERROR => 'MCP protocol communication error',
            self::SERVER_UNAVAILABLE => 'MCP server is unavailable',
        };
    }

    public function getRecoveryHint(): string
    {
        return match($this) {
            self::TOOL_NOT_FOUND => 'Check tool name and available MCP tools',
            self::TOOL_EXECUTION_FAILED => 'Review tool logs and fix underlying issue',
            self::INVALID_TOOL_ARGUMENTS => 'Provide valid arguments according to tool schema',
            self::RESOURCE_NOT_FOUND => 'Verify resource URI and existence',
            self::PROTOCOL_ERROR => 'Check MCP protocol version and message format',
            self::SERVER_UNAVAILABLE => 'Start MCP server or check server configuration',
        };
    }

    public function isRecoverable(): bool
    {
        return match($this) {
            self::TOOL_NOT_FOUND,
            self::RESOURCE_NOT_FOUND => false,
            default => true,
        };
    }

    public function getRetryAfterSeconds(): ?int
    {
        return match($this) {
            self::SERVER_UNAVAILABLE => 30,
            default => null,
        };
    }
}
