using System.Net;

namespace StellaOps.Feedser.Source.Ru.Bdu.Configuration;

/// <summary>
/// Connector options for the Russian BDU archive ingestion pipeline.
/// </summary>
public sealed class RuBduOptions
{
    public const string HttpClientName = "ru-bdu";

    private static readonly TimeSpan DefaultRequestTimeout = TimeSpan.FromMinutes(2);
    private static readonly TimeSpan DefaultFailureBackoff = TimeSpan.FromMinutes(30);

    /// <summary>
    /// Base endpoint used for resolving relative resource paths.
    /// </summary>
    public Uri BaseAddress { get; set; } = new("https://bdu.fstec.ru/", UriKind.Absolute);

    /// <summary>
    /// Relative path to the zipped vulnerability dataset.
    /// </summary>
    public string DataArchivePath { get; set; } = "files/documents/vulxml.zip";

    /// <summary>
    /// HTTP timeout applied when downloading the archive.
    /// </summary>
    public TimeSpan RequestTimeout { get; set; } = DefaultRequestTimeout;

    /// <summary>
    /// Backoff applied when the remote endpoint fails to serve the archive.
    /// </summary>
    public TimeSpan FailureBackoff { get; set; } = DefaultFailureBackoff;

    /// <summary>
    /// User-Agent header used for outbound requests.
    /// </summary>
    public string UserAgent { get; set; } = "StellaOps/Feedser (+https://stella-ops.org)";

    /// <summary>
    /// Accept-Language preference sent with outbound requests.
    /// </summary>
    public string AcceptLanguage { get; set; } = "ru-RU,ru;q=0.9,en-US;q=0.6,en;q=0.4";

    /// <summary>
    /// Maximum number of vulnerabilities ingested per fetch cycle.
    /// </summary>
    public int MaxVulnerabilitiesPerFetch { get; set; } = 500;

    /// <summary>
    /// Returns the absolute URI for the archive download.
    /// </summary>
    public Uri DataArchiveUri => new(BaseAddress, DataArchivePath);

    /// <summary>
    /// Optional directory for caching the most recent archive (relative paths resolve under the content root).
    /// </summary>
    public string? CacheDirectory { get; set; } = null;

    public void Validate()
    {
        if (BaseAddress is null || !BaseAddress.IsAbsoluteUri)
        {
            throw new InvalidOperationException("RuBdu BaseAddress must be an absolute URI.");
        }

        if (string.IsNullOrWhiteSpace(DataArchivePath))
        {
            throw new InvalidOperationException("RuBdu DataArchivePath must be provided.");
        }

        if (RequestTimeout <= TimeSpan.Zero)
        {
            throw new InvalidOperationException("RuBdu RequestTimeout must be positive.");
        }

        if (FailureBackoff < TimeSpan.Zero)
        {
            throw new InvalidOperationException("RuBdu FailureBackoff cannot be negative.");
        }

        if (string.IsNullOrWhiteSpace(UserAgent))
        {
            throw new InvalidOperationException("RuBdu UserAgent cannot be empty.");
        }

        if (string.IsNullOrWhiteSpace(AcceptLanguage))
        {
            throw new InvalidOperationException("RuBdu AcceptLanguage cannot be empty.");
        }

        if (MaxVulnerabilitiesPerFetch <= 0)
        {
            throw new InvalidOperationException("RuBdu MaxVulnerabilitiesPerFetch must be greater than zero.");
        }

        if (CacheDirectory is not null && CacheDirectory.Trim().Length == 0)
        {
            throw new InvalidOperationException("RuBdu CacheDirectory cannot be whitespace.");
        }
    }
}
