using ColaFlow.Modules.Mcp.Contracts.JsonRpc;

namespace ColaFlow.Modules.Mcp.Domain.Exceptions;

/// <summary>
/// Base exception class for all MCP-related exceptions
/// Maps to JSON-RPC 2.0 error responses
/// </summary>
public abstract class McpException : Exception
{
    /// <summary>
    /// JSON-RPC error code
    /// </summary>
    public JsonRpcErrorCode ErrorCode { get; }

    /// <summary>
    /// Additional error data (optional, can be any JSON-serializable object)
    /// </summary>
    public object? ErrorData { get; }

    /// <summary>
    /// Initializes a new instance of the <see cref="McpException"/> class
    /// </summary>
    /// <param name="errorCode">JSON-RPC error code</param>
    /// <param name="message">Error message</param>
    /// <param name="errorData">Additional error data (optional)</param>
    /// <param name="innerException">Inner exception (optional)</param>
    protected McpException(
        JsonRpcErrorCode errorCode,
        string message,
        object? errorData = null,
        Exception? innerException = null)
        : base(message, innerException)
    {
        ErrorCode = errorCode;
        ErrorData = errorData;
    }

    /// <summary>
    /// Converts this exception to a JSON-RPC error object
    /// </summary>
    /// <returns>JSON-RPC error object</returns>
    public JsonRpcError ToJsonRpcError()
    {
        return new JsonRpcError(ErrorCode, Message, ErrorData);
    }

    /// <summary>
    /// Gets the HTTP status code that should be returned for this error
    /// </summary>
    /// <returns>HTTP status code</returns>
    public virtual int GetHttpStatusCode()
    {
        return ErrorCode switch
        {
            JsonRpcErrorCode.Unauthorized => 401,
            JsonRpcErrorCode.Forbidden => 403,
            JsonRpcErrorCode.NotFound => 404,
            JsonRpcErrorCode.ValidationFailed => 422,
            JsonRpcErrorCode.ParseError => 400,
            JsonRpcErrorCode.InvalidRequest => 400,
            JsonRpcErrorCode.MethodNotFound => 404,
            JsonRpcErrorCode.InvalidParams => 400,
            JsonRpcErrorCode.InternalError => 500,
            _ => 500
        };
    }
}
