using System;
using System.Collections.Generic;

namespace StellaOps.Feedser.WebService.Options;

public sealed class FeedserOptions
{
    public StorageOptions Storage { get; set; } = new();

    public PluginOptions Plugins { get; set; } = new();

    public TelemetryOptions Telemetry { get; set; } = new();

    public AuthorityOptions Authority { get; set; } = new();

    public sealed class StorageOptions
    {
        public string Driver { get; set; } = "mongo";

        public string Dsn { get; set; } = string.Empty;

        public string? Database { get; set; }

        public int CommandTimeoutSeconds { get; set; } = 30;
    }

    public sealed class PluginOptions
    {
        public string? BaseDirectory { get; set; }

        public string? Directory { get; set; }

        public IList<string> SearchPatterns { get; set; } = new List<string>();
    }

    public sealed class TelemetryOptions
    {
        public bool Enabled { get; set; } = true;

        public bool EnableTracing { get; set; } = true;

        public bool EnableMetrics { get; set; } = true;

        public bool EnableLogging { get; set; } = true;

        public string MinimumLogLevel { get; set; } = "Information";

        public string? ServiceName { get; set; }

        public string? OtlpEndpoint { get; set; }

        public IDictionary<string, string> OtlpHeaders { get; set; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

        public IDictionary<string, string> ResourceAttributes { get; set; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

        public bool ExportConsole { get; set; }
    }

    public sealed class AuthorityOptions
    {
        public bool Enabled { get; set; }

        public bool AllowAnonymousFallback { get; set; } = true;

        public string Issuer { get; set; } = string.Empty;

        public string? MetadataAddress { get; set; }

        public bool RequireHttpsMetadata { get; set; } = true;

        public int BackchannelTimeoutSeconds { get; set; } = 30;

        public int TokenClockSkewSeconds { get; set; } = 60;

        public IList<string> Audiences { get; set; } = new List<string>();

        public IList<string> RequiredScopes { get; set; } = new List<string>();

        public IList<string> BypassNetworks { get; set; } = new List<string>();

        public string? ClientId { get; set; }

        public string? ClientSecret { get; set; }

        public string? ClientSecretFile { get; set; }

        public IList<string> ClientScopes { get; set; } = new List<string>();

        public ResilienceOptions Resilience { get; set; } = new();

        public sealed class ResilienceOptions
        {
            public bool? EnableRetries { get; set; }

            public IList<TimeSpan> RetryDelays { get; set; } = new List<TimeSpan>();

            public bool? AllowOfflineCacheFallback { get; set; }

            public TimeSpan? OfflineCacheTolerance { get; set; }
        }
    }
}
