using System.Net;

namespace ScadaLink.ExternalSystemGateway;

/// <summary>
/// WP-8: Classifies HTTP errors as transient or permanent.
/// Transient: connection refused, timeout, HTTP 408/429/5xx.
/// Permanent: HTTP 4xx (except 408/429).
/// </summary>
public static class ErrorClassifier
{
    /// <summary>
    /// Determines whether an HTTP status code represents a transient failure.
    /// </summary>
    public static bool IsTransient(HttpStatusCode statusCode)
    {
        var code = (int)statusCode;
        return code >= 500 || code == 408 || code == 429;
    }

    /// <summary>
    /// Determines whether an exception represents a transient failure.
    /// </summary>
    public static bool IsTransient(Exception exception)
    {
        return exception is HttpRequestException
            or TaskCanceledException
            or TimeoutException
            or OperationCanceledException;
    }

    /// <summary>
    /// Creates a TransientException for S&amp;F buffering.
    /// </summary>
    public static TransientExternalSystemException AsTransient(string message, Exception? inner = null)
    {
        return new TransientExternalSystemException(message, inner);
    }
}

/// <summary>
/// Exception type that signals a transient failure suitable for store-and-forward retry.
/// </summary>
public class TransientExternalSystemException : Exception
{
    public TransientExternalSystemException(string message, Exception? innerException = null)
        : base(message, innerException) { }
}

/// <summary>
/// Exception type that signals a permanent failure (should not be retried).
/// </summary>
public class PermanentExternalSystemException : Exception
{
    public int? HttpStatusCode { get; }

    public PermanentExternalSystemException(string message, int? httpStatusCode = null, Exception? innerException = null)
        : base(message, innerException)
    {
        HttpStatusCode = httpStatusCode;
    }
}
