using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Mongo2Go;
using StellaOps.Feedser.Core.Jobs;
using StellaOps.Feedser.WebService.Jobs;
using StellaOps.Feedser.WebService.Options;
using Xunit.Sdk;
using StellaOps.Auth.Abstractions;
using StellaOps.Auth.Client;

namespace StellaOps.Feedser.WebService.Tests;

public sealed class WebServiceEndpointsTests : IAsyncLifetime
{
    private MongoDbRunner _runner = null!;
    private FeedserApplicationFactory _factory = null!;

    public Task InitializeAsync()
    {
        _runner = MongoDbRunner.Start(singleNodeReplSet: true);
        _factory = new FeedserApplicationFactory(_runner.ConnectionString);
        return Task.CompletedTask;
    }

    public Task DisposeAsync()
    {
        _factory.Dispose();
        _runner.Dispose();
        return Task.CompletedTask;
    }

    [Fact]
    public async Task HealthAndReadyEndpointsRespond()
    {
        using var client = _factory.CreateClient();

        var healthResponse = await client.GetAsync("/health");
        if (!healthResponse.IsSuccessStatusCode)
        {
            var body = await healthResponse.Content.ReadAsStringAsync();
            throw new Xunit.Sdk.XunitException($"/health failed: {(int)healthResponse.StatusCode} {body}");
        }

        var readyResponse = await client.GetAsync("/ready");
        if (!readyResponse.IsSuccessStatusCode)
        {
            var body = await readyResponse.Content.ReadAsStringAsync();
            throw new Xunit.Sdk.XunitException($"/ready failed: {(int)readyResponse.StatusCode} {body}");
        }

        var healthPayload = await healthResponse.Content.ReadFromJsonAsync<HealthPayload>();
        Assert.NotNull(healthPayload);
        Assert.Equal("healthy", healthPayload!.Status);
        Assert.Equal("mongo", healthPayload.Storage.Driver);

        var readyPayload = await readyResponse.Content.ReadFromJsonAsync<ReadyPayload>();
        Assert.NotNull(readyPayload);
        Assert.Equal("ready", readyPayload!.Status);
        Assert.Equal("ready", readyPayload.Mongo.Status);
    }

    [Fact]
    public async Task JobsEndpointsReturnExpectedStatuses()
    {
        using var client = _factory.CreateClient();

        var definitions = await client.GetAsync("/jobs/definitions");
        if (!definitions.IsSuccessStatusCode)
        {
            var body = await definitions.Content.ReadAsStringAsync();
            throw new Xunit.Sdk.XunitException($"/jobs/definitions failed: {(int)definitions.StatusCode} {body}");
        }

        var trigger = await client.PostAsync("/jobs/unknown", new StringContent("{}", System.Text.Encoding.UTF8, "application/json"));
        if (trigger.StatusCode != HttpStatusCode.NotFound)
        {
            var payload = await trigger.Content.ReadAsStringAsync();
            throw new Xunit.Sdk.XunitException($"/jobs/unknown expected 404, got {(int)trigger.StatusCode}: {payload}");
        }
        var problem = await trigger.Content.ReadFromJsonAsync<ProblemDocument>();
        Assert.NotNull(problem);
        Assert.Equal("https://stellaops.org/problems/not-found", problem!.Type);
        Assert.Equal(404, problem.Status);
    }

    [Fact]
    public async Task JobRunEndpointReturnsProblemWhenNotFound()
    {
        using var client = _factory.CreateClient();
        var response = await client.GetAsync($"/jobs/{Guid.NewGuid()}");
        if (response.StatusCode != HttpStatusCode.NotFound)
        {
            var body = await response.Content.ReadAsStringAsync();
            throw new Xunit.Sdk.XunitException($"/jobs/{{id}} expected 404, got {(int)response.StatusCode}: {body}");
        }
        var problem = await response.Content.ReadFromJsonAsync<ProblemDocument>();
        Assert.NotNull(problem);
        Assert.Equal("https://stellaops.org/problems/not-found", problem!.Type);
    }

    [Fact]
    public async Task JobTriggerMapsCoordinatorOutcomes()
    {
        var handler = _factory.Services.GetRequiredService<StubJobCoordinator>();
        using var client = _factory.CreateClient();

        handler.NextResult = JobTriggerResult.AlreadyRunning("busy");
        var conflict = await client.PostAsync("/jobs/test", JsonContent.Create(new JobTriggerRequest()));
        if (conflict.StatusCode != HttpStatusCode.Conflict)
        {
            var payload = await conflict.Content.ReadAsStringAsync();
            throw new Xunit.Sdk.XunitException($"Conflict path expected 409, got {(int)conflict.StatusCode}: {payload}");
        }
        var conflictProblem = await conflict.Content.ReadFromJsonAsync<ProblemDocument>();
        Assert.NotNull(conflictProblem);
        Assert.Equal("https://stellaops.org/problems/conflict", conflictProblem!.Type);

        handler.NextResult = JobTriggerResult.Accepted(new JobRunSnapshot(Guid.NewGuid(), "demo", JobRunStatus.Pending, DateTimeOffset.UtcNow, null, null, "api", null, null, null, null, new Dictionary<string, object?>()));
        var accepted = await client.PostAsync("/jobs/test", JsonContent.Create(new JobTriggerRequest()));
        if (accepted.StatusCode != HttpStatusCode.Accepted)
        {
            var payload = await accepted.Content.ReadAsStringAsync();
            throw new Xunit.Sdk.XunitException($"Accepted path expected 202, got {(int)accepted.StatusCode}: {payload}");
        }
        Assert.NotNull(accepted.Headers.Location);
        var acceptedPayload = await accepted.Content.ReadFromJsonAsync<JobRunPayload>();
        Assert.NotNull(acceptedPayload);

        handler.NextResult = JobTriggerResult.Failed(new JobRunSnapshot(Guid.NewGuid(), "demo", JobRunStatus.Failed, DateTimeOffset.UtcNow, null, DateTimeOffset.UtcNow, "api", null, "err", null, null, new Dictionary<string, object?>()), "boom");
        var failed = await client.PostAsync("/jobs/test", JsonContent.Create(new JobTriggerRequest()));
        if (failed.StatusCode != HttpStatusCode.InternalServerError)
        {
            var payload = await failed.Content.ReadAsStringAsync();
            throw new Xunit.Sdk.XunitException($"Failed path expected 500, got {(int)failed.StatusCode}: {payload}");
        }
        var failureProblem = await failed.Content.ReadFromJsonAsync<ProblemDocument>();
        Assert.NotNull(failureProblem);
        Assert.Equal("https://stellaops.org/problems/job-failure", failureProblem!.Type);
    }

    [Fact]
    public async Task JobsEndpointsExposeJobData()
    {
        var handler = _factory.Services.GetRequiredService<StubJobCoordinator>();
        var now = DateTimeOffset.UtcNow;
        var run = new JobRunSnapshot(
            Guid.NewGuid(),
            "demo",
            JobRunStatus.Succeeded,
            now,
            now,
            now.AddSeconds(2),
            "api",
            "hash",
            null,
            TimeSpan.FromMinutes(5),
            TimeSpan.FromMinutes(1),
            new Dictionary<string, object?> { ["key"] = "value" });

        handler.Definitions = new[]
        {
            new JobDefinition("demo", typeof(DemoJob), TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(1), "*/5 * * * *", true)
        };
        handler.LastRuns["demo"] = run;
        handler.RecentRuns = new[] { run };
        handler.ActiveRuns = Array.Empty<JobRunSnapshot>();
        handler.Runs[run.RunId] = run;

        try
        {
            using var client = _factory.CreateClient();

            var definitions = await client.GetFromJsonAsync<List<JobDefinitionPayload>>("/jobs/definitions");
            Assert.NotNull(definitions);
            Assert.Single(definitions!);
            Assert.Equal("demo", definitions![0].Kind);
            Assert.NotNull(definitions[0].LastRun);
            Assert.Equal(run.RunId, definitions[0].LastRun!.RunId);

            var runPayload = await client.GetFromJsonAsync<JobRunPayload>($"/jobs/{run.RunId}");
            Assert.NotNull(runPayload);
            Assert.Equal(run.RunId, runPayload!.RunId);
            Assert.Equal("Succeeded", runPayload.Status);

            var runs = await client.GetFromJsonAsync<List<JobRunPayload>>("/jobs?kind=demo&limit=5");
            Assert.NotNull(runs);
            Assert.Single(runs!);
            Assert.Equal(run.RunId, runs![0].RunId);

            var runsByDefinition = await client.GetFromJsonAsync<List<JobRunPayload>>("/jobs/definitions/demo/runs");
            Assert.NotNull(runsByDefinition);
            Assert.Single(runsByDefinition!);

            var active = await client.GetFromJsonAsync<List<JobRunPayload>>("/jobs/active");
            Assert.NotNull(active);
            Assert.Empty(active!);
        }
        finally
        {
            handler.Definitions = Array.Empty<JobDefinition>();
            handler.RecentRuns = Array.Empty<JobRunSnapshot>();
            handler.ActiveRuns = Array.Empty<JobRunSnapshot>();
            handler.Runs.Clear();
            handler.LastRuns.Clear();
        }
    }

    [Fact]
    public async Task JobsEndpointsAllowBypassWhenAuthorityEnabled()
    {
        var environment = new Dictionary<string, string?>
        {
            ["FEEDSER_AUTHORITY__ENABLED"] = "true",
            ["FEEDSER_AUTHORITY__ALLOWANONYMOUSFALLBACK"] = "false",
            ["FEEDSER_AUTHORITY__ISSUER"] = "https://authority.example",
            ["FEEDSER_AUTHORITY__REQUIREHTTPSMETADATA"] = "false",
            ["FEEDSER_AUTHORITY__AUDIENCES__0"] = "api://feedser",
            ["FEEDSER_AUTHORITY__REQUIREDSCOPES__0"] = StellaOpsScopes.FeedserJobsTrigger,
            ["FEEDSER_AUTHORITY__BYPASSNETWORKS__0"] = "127.0.0.1/32",
            ["FEEDSER_AUTHORITY__BYPASSNETWORKS__1"] = "::1/128",
            ["FEEDSER_AUTHORITY__CLIENTID"] = "feedser-jobs",
            ["FEEDSER_AUTHORITY__CLIENTSECRET"] = "test-secret",
            ["FEEDSER_AUTHORITY__CLIENTSCOPES__0"] = StellaOpsScopes.FeedserJobsTrigger,
        };

        using var factory = new FeedserApplicationFactory(
            _runner.ConnectionString,
            authority =>
            {
                authority.Enabled = true;
                authority.AllowAnonymousFallback = false;
                authority.Issuer = "https://authority.example";
                authority.RequireHttpsMetadata = false;
                authority.Audiences.Clear();
                authority.Audiences.Add("api://feedser");
                authority.RequiredScopes.Clear();
                authority.RequiredScopes.Add(StellaOpsScopes.FeedserJobsTrigger);
                authority.BypassNetworks.Clear();
                authority.BypassNetworks.Add("127.0.0.1/32");
                authority.BypassNetworks.Add("::1/128");
                authority.ClientId = "feedser-jobs";
                authority.ClientSecret = "test-secret";
            },
            environment);

        var handler = factory.Services.GetRequiredService<StubJobCoordinator>();
        handler.Definitions = new[] { new JobDefinition("demo", typeof(DemoJob), TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(1), null, true) };

        using var client = factory.CreateClient();
        client.DefaultRequestHeaders.Add("X-Test-RemoteAddr", "127.0.0.1");
        var response = await client.GetAsync("/jobs/definitions");

        Assert.Equal(HttpStatusCode.OK, response.StatusCode);

        var auditLogs = factory.LoggerProvider.Snapshot("Feedser.Authorization.Audit");
        var bypassLog = Assert.Single(auditLogs, entry => entry.TryGetState("Bypass", out var state) && state is bool flag && flag);
        Assert.True(bypassLog.TryGetState("RemoteAddress", out var remoteObj) && string.Equals(remoteObj?.ToString(), "127.0.0.1", StringComparison.Ordinal));
        Assert.True(bypassLog.TryGetState("StatusCode", out var statusObj) && Convert.ToInt32(statusObj) == (int)HttpStatusCode.OK);
    }

    [Fact]
    public async Task JobsEndpointsRequireAuthWhenFallbackDisabled()
    {
        var enforcementEnvironment = new Dictionary<string, string?>
        {
            ["FEEDSER_AUTHORITY__ENABLED"] = "true",
            ["FEEDSER_AUTHORITY__ALLOWANONYMOUSFALLBACK"] = "false",
            ["FEEDSER_AUTHORITY__ISSUER"] = "https://authority.example",
            ["FEEDSER_AUTHORITY__REQUIREHTTPSMETADATA"] = "false",
            ["FEEDSER_AUTHORITY__AUDIENCES__0"] = "api://feedser",
            ["FEEDSER_AUTHORITY__REQUIREDSCOPES__0"] = StellaOpsScopes.FeedserJobsTrigger,
            ["FEEDSER_AUTHORITY__CLIENTID"] = "feedser-jobs",
            ["FEEDSER_AUTHORITY__CLIENTSECRET"] = "test-secret",
            ["FEEDSER_AUTHORITY__CLIENTSCOPES__0"] = StellaOpsScopes.FeedserJobsTrigger,
        };

        using var factory = new FeedserApplicationFactory(
            _runner.ConnectionString,
            authority =>
            {
                authority.Enabled = true;
                authority.AllowAnonymousFallback = false;
                authority.Issuer = "https://authority.example";
                authority.RequireHttpsMetadata = false;
                authority.Audiences.Clear();
                authority.Audiences.Add("api://feedser");
                authority.RequiredScopes.Clear();
                authority.RequiredScopes.Add(StellaOpsScopes.FeedserJobsTrigger);
                authority.BypassNetworks.Clear();
                authority.ClientId = "feedser-jobs";
                authority.ClientSecret = "test-secret";
            },
            enforcementEnvironment);

        var resolved = factory.Services.GetRequiredService<IOptions<FeedserOptions>>().Value;
        Assert.False(resolved.Authority.AllowAnonymousFallback);

        using var client = factory.CreateClient();
        client.DefaultRequestHeaders.Add("X-Test-RemoteAddr", "127.0.0.1");
        var response = await client.GetAsync("/jobs/definitions");

        Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);

        var auditLogs = factory.LoggerProvider.Snapshot("Feedser.Authorization.Audit");
        var enforcementLog = Assert.Single(auditLogs);
        Assert.True(enforcementLog.TryGetState("BypassAllowed", out var bypassAllowedObj) && bypassAllowedObj is bool bypassAllowed && bypassAllowed == false);
        Assert.True(enforcementLog.TryGetState("HasPrincipal", out var principalObj) && principalObj is bool hasPrincipal && hasPrincipal == false);
    }

    [Fact]
    public void AuthorityClientResilienceOptionsAreBound()
    {
        var environment = new Dictionary<string, string?>
        {
            ["FEEDSER_AUTHORITY__ENABLED"] = "true",
            ["FEEDSER_AUTHORITY__ISSUER"] = "https://authority.example",
            ["FEEDSER_AUTHORITY__REQUIREHTTPSMETADATA"] = "false",
            ["FEEDSER_AUTHORITY__AUDIENCES__0"] = "api://feedser",
            ["FEEDSER_AUTHORITY__REQUIREDSCOPES__0"] = StellaOpsScopes.FeedserJobsTrigger,
            ["FEEDSER_AUTHORITY__CLIENTSCOPES__0"] = StellaOpsScopes.FeedserJobsTrigger,
            ["FEEDSER_AUTHORITY__BACKCHANNELTIMEOUTSECONDS"] = "45",
            ["FEEDSER_AUTHORITY__RESILIENCE__ENABLERETRIES"] = "true",
            ["FEEDSER_AUTHORITY__RESILIENCE__RETRYDELAYS__0"] = "00:00:02",
            ["FEEDSER_AUTHORITY__RESILIENCE__RETRYDELAYS__1"] = "00:00:04",
            ["FEEDSER_AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK"] = "false",
            ["FEEDSER_AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE"] = "00:02:30"
        };

        using var factory = new FeedserApplicationFactory(
            _runner.ConnectionString,
            authority =>
            {
                authority.Enabled = true;
                authority.Issuer = "https://authority.example";
                authority.RequireHttpsMetadata = false;
                authority.Audiences.Clear();
                authority.Audiences.Add("api://feedser");
                authority.RequiredScopes.Clear();
                authority.RequiredScopes.Add(StellaOpsScopes.FeedserJobsTrigger);
                authority.ClientScopes.Clear();
                authority.ClientScopes.Add(StellaOpsScopes.FeedserJobsTrigger);
                authority.BackchannelTimeoutSeconds = 45;
            },
            environment);

        var monitor = factory.Services.GetRequiredService<IOptionsMonitor<StellaOpsAuthClientOptions>>();
        var options = monitor.CurrentValue;

        Assert.Equal("https://authority.example", options.Authority);
        Assert.Equal(TimeSpan.FromSeconds(45), options.HttpTimeout);
        Assert.Equal(new[] { StellaOpsScopes.FeedserJobsTrigger }, options.NormalizedScopes);
        Assert.Equal(new[] { TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4) }, options.NormalizedRetryDelays);
        Assert.False(options.AllowOfflineCacheFallback);
        Assert.Equal(TimeSpan.FromSeconds(150), options.OfflineCacheTolerance);
    }

    private sealed class FeedserApplicationFactory : WebApplicationFactory<Program>
    {
        private readonly string _connectionString;
        private readonly string? _previousDsn;
        private readonly string? _previousDriver;
        private readonly string? _previousTimeout;
        private readonly string? _previousTelemetryEnabled;
        private readonly string? _previousTelemetryLogging;
        private readonly string? _previousTelemetryTracing;
        private readonly string? _previousTelemetryMetrics;
        private readonly Action<FeedserOptions.AuthorityOptions>? _authorityConfigure;
        private readonly IDictionary<string, string?> _additionalPreviousEnvironment = new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
        public CollectingLoggerProvider LoggerProvider { get; } = new();

        public FeedserApplicationFactory(
            string connectionString,
            Action<FeedserOptions.AuthorityOptions>? authorityConfigure = null,
            IDictionary<string, string?>? environmentOverrides = null)
        {
            _connectionString = connectionString;
            _authorityConfigure = authorityConfigure;
            _previousDsn = Environment.GetEnvironmentVariable("FEEDSER_STORAGE__DSN");
            _previousDriver = Environment.GetEnvironmentVariable("FEEDSER_STORAGE__DRIVER");
            _previousTimeout = Environment.GetEnvironmentVariable("FEEDSER_STORAGE__COMMANDTIMEOUTSECONDS");
            _previousTelemetryEnabled = Environment.GetEnvironmentVariable("FEEDSER_TELEMETRY__ENABLED");
            _previousTelemetryLogging = Environment.GetEnvironmentVariable("FEEDSER_TELEMETRY__ENABLELOGGING");
            _previousTelemetryTracing = Environment.GetEnvironmentVariable("FEEDSER_TELEMETRY__ENABLETRACING");
            _previousTelemetryMetrics = Environment.GetEnvironmentVariable("FEEDSER_TELEMETRY__ENABLEMETRICS");
            Environment.SetEnvironmentVariable("FEEDSER_STORAGE__DSN", connectionString);
            Environment.SetEnvironmentVariable("FEEDSER_STORAGE__DRIVER", "mongo");
            Environment.SetEnvironmentVariable("FEEDSER_STORAGE__COMMANDTIMEOUTSECONDS", "30");
            Environment.SetEnvironmentVariable("FEEDSER_TELEMETRY__ENABLED", "false");
            Environment.SetEnvironmentVariable("FEEDSER_TELEMETRY__ENABLELOGGING", "false");
            Environment.SetEnvironmentVariable("FEEDSER_TELEMETRY__ENABLETRACING", "false");
            Environment.SetEnvironmentVariable("FEEDSER_TELEMETRY__ENABLEMETRICS", "false");
            if (environmentOverrides is not null)
            {
                foreach (var kvp in environmentOverrides)
                {
                    var previous = Environment.GetEnvironmentVariable(kvp.Key);
                    _additionalPreviousEnvironment[kvp.Key] = previous;
                    Environment.SetEnvironmentVariable(kvp.Key, kvp.Value);
                }
            }
        }

        protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            builder.ConfigureAppConfiguration((context, configurationBuilder) =>
            {
                var settings = new Dictionary<string, string?>
                {
                    ["Plugins:Directory"] = Path.Combine(context.HostingEnvironment.ContentRootPath, "PluginBinaries"),
                };

                configurationBuilder.AddInMemoryCollection(settings!);
            });

            builder.ConfigureLogging(logging =>
            {
                logging.AddProvider(LoggerProvider);
            });

            builder.ConfigureServices(services =>
            {
                services.AddSingleton<StubJobCoordinator>();
                services.AddSingleton<IJobCoordinator>(sp => sp.GetRequiredService<StubJobCoordinator>());
                services.PostConfigure<FeedserOptions>(options =>
                {
                    options.Storage.Driver = "mongo";
                    options.Storage.Dsn = _connectionString;
                    options.Storage.CommandTimeoutSeconds = 30;
                    options.Plugins.Directory ??= Path.Combine(AppContext.BaseDirectory, "PluginBinaries");
                    options.Telemetry.Enabled = false;
                    options.Telemetry.EnableLogging = false;
                    options.Telemetry.EnableTracing = false;
                    options.Telemetry.EnableMetrics = false;
                    options.Authority ??= new FeedserOptions.AuthorityOptions();
                    _authorityConfigure?.Invoke(options.Authority);
                });
            });

            builder.ConfigureTestServices(services =>
            {
                services.AddSingleton<IStartupFilter, RemoteIpStartupFilter>();
            });
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            Environment.SetEnvironmentVariable("FEEDSER_STORAGE__DSN", _previousDsn);
            Environment.SetEnvironmentVariable("FEEDSER_STORAGE__DRIVER", _previousDriver);
            Environment.SetEnvironmentVariable("FEEDSER_STORAGE__COMMANDTIMEOUTSECONDS", _previousTimeout);
            Environment.SetEnvironmentVariable("FEEDSER_TELEMETRY__ENABLED", _previousTelemetryEnabled);
            Environment.SetEnvironmentVariable("FEEDSER_TELEMETRY__ENABLELOGGING", _previousTelemetryLogging);
            Environment.SetEnvironmentVariable("FEEDSER_TELEMETRY__ENABLETRACING", _previousTelemetryTracing);
            Environment.SetEnvironmentVariable("FEEDSER_TELEMETRY__ENABLEMETRICS", _previousTelemetryMetrics);
            foreach (var kvp in _additionalPreviousEnvironment)
            {
                Environment.SetEnvironmentVariable(kvp.Key, kvp.Value);
            }

            LoggerProvider.Dispose();
        }

        private sealed class RemoteIpStartupFilter : IStartupFilter
        {
            public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
            {
                return app =>
                {
                    app.Use(async (context, nextMiddleware) =>
                    {
                        if (context.Request.Headers.TryGetValue("X-Test-RemoteAddr", out var values)
                            && values.Count > 0
                            && IPAddress.TryParse(values[0], out var remote))
                        {
                            context.Connection.RemoteIpAddress = remote;
                        }

                        await nextMiddleware();
                    });

                    next(app);
                };
            }
        }

        public sealed record LogEntry(
            string LoggerName,
            LogLevel Level,
            EventId EventId,
            string? Message,
            Exception? Exception,
            IReadOnlyList<KeyValuePair<string, object?>> State)
        {
            public bool TryGetState(string name, out object? value)
            {
                foreach (var kvp in State)
                {
                    if (string.Equals(kvp.Key, name, StringComparison.Ordinal))
                    {
                        value = kvp.Value;
                        return true;
                    }
                }

                value = null;
                return false;
            }
        }

        public sealed class CollectingLoggerProvider : ILoggerProvider
        {
            private readonly object syncRoot = new();
            private readonly List<LogEntry> entries = new();
            private bool disposed;

            public ILogger CreateLogger(string categoryName) => new CollectingLogger(categoryName, this);

            public IReadOnlyList<LogEntry> Snapshot(string loggerName)
            {
                lock (syncRoot)
                {
                    return entries
                        .Where(entry => string.Equals(entry.LoggerName, loggerName, StringComparison.Ordinal))
                        .ToArray();
                }
            }

            public void Dispose()
            {
                disposed = true;
                lock (syncRoot)
                {
                    entries.Clear();
                }
            }

            private void Append(LogEntry entry)
            {
                if (disposed)
                {
                    return;
                }

                lock (syncRoot)
                {
                    entries.Add(entry);
                }
            }

            private sealed class CollectingLogger : ILogger
            {
                private readonly string categoryName;
                private readonly CollectingLoggerProvider provider;

                public CollectingLogger(string categoryName, CollectingLoggerProvider provider)
                {
                    this.categoryName = categoryName;
                    this.provider = provider;
                }

                public IDisposable? BeginScope<TState>(TState state) where TState : notnull => NullScope.Instance;

                public bool IsEnabled(LogLevel logLevel) => true;

                public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
                {
                    if (formatter is null)
                    {
                        throw new ArgumentNullException(nameof(formatter));
                    }

                    var message = formatter(state, exception);
                    var kvps = ExtractState(state);
                    var entry = new LogEntry(categoryName, logLevel, eventId, message, exception, kvps);
                    provider.Append(entry);
                }

                private static IReadOnlyList<KeyValuePair<string, object?>> ExtractState<TState>(TState state)
                {
                    if (state is IReadOnlyList<KeyValuePair<string, object?>> list)
                    {
                        return list;
                    }

                    if (state is IEnumerable<KeyValuePair<string, object?>> enumerable)
                    {
                        return enumerable.ToArray();
                    }

                    if (state is null)
                    {
                        return Array.Empty<KeyValuePair<string, object?>>();
                    }

                    return new[] { new KeyValuePair<string, object?>("State", state) };
                }
            }

            private sealed class NullScope : IDisposable
            {
                public static readonly NullScope Instance = new();
                public void Dispose()
                {
                }
            }
        }
    }

    private sealed record HealthPayload(string Status, DateTimeOffset StartedAt, double UptimeSeconds, StoragePayload Storage, TelemetryPayload Telemetry);

    private sealed record StoragePayload(string Driver, bool Completed, DateTimeOffset? CompletedAt, double? DurationMs);

    private sealed record TelemetryPayload(bool Enabled, bool Tracing, bool Metrics, bool Logging);

    private sealed record ReadyPayload(string Status, DateTimeOffset StartedAt, double UptimeSeconds, ReadyMongoPayload Mongo);

    private sealed record ReadyMongoPayload(string Status, double? LatencyMs, DateTimeOffset? CheckedAt, string? Error);

    private sealed record JobDefinitionPayload(string Kind, bool Enabled, string? CronExpression, TimeSpan Timeout, TimeSpan LeaseDuration, JobRunPayload? LastRun);

    private sealed record JobRunPayload(Guid RunId, string Kind, string Status, string Trigger, DateTimeOffset CreatedAt, DateTimeOffset? StartedAt, DateTimeOffset? CompletedAt, string? Error, TimeSpan? Duration, Dictionary<string, object?> Parameters);

    private sealed record ProblemDocument(string? Type, string? Title, int? Status, string? Detail, string? Instance);

    private sealed class DemoJob : IJob
    {
        public Task ExecuteAsync(JobExecutionContext context, CancellationToken cancellationToken) => Task.CompletedTask;
    }

    private sealed class StubJobCoordinator : IJobCoordinator
    {
        public JobTriggerResult NextResult { get; set; } = JobTriggerResult.NotFound("not set");

        public IReadOnlyList<JobDefinition> Definitions { get; set; } = Array.Empty<JobDefinition>();

        public IReadOnlyList<JobRunSnapshot> RecentRuns { get; set; } = Array.Empty<JobRunSnapshot>();

        public IReadOnlyList<JobRunSnapshot> ActiveRuns { get; set; } = Array.Empty<JobRunSnapshot>();

        public Dictionary<Guid, JobRunSnapshot> Runs { get; } = new();

        public Dictionary<string, JobRunSnapshot?> LastRuns { get; } = new(StringComparer.Ordinal);

        public Task<JobTriggerResult> TriggerAsync(string kind, IReadOnlyDictionary<string, object?>? parameters, string trigger, CancellationToken cancellationToken)
            => Task.FromResult(NextResult);

        public Task<IReadOnlyList<JobDefinition>> GetDefinitionsAsync(CancellationToken cancellationToken)
            => Task.FromResult(Definitions);

        public Task<IReadOnlyList<JobRunSnapshot>> GetRecentRunsAsync(string? kind, int limit, CancellationToken cancellationToken)
        {
            IEnumerable<JobRunSnapshot> query = RecentRuns;
            if (!string.IsNullOrWhiteSpace(kind))
            {
                query = query.Where(run => string.Equals(run.Kind, kind, StringComparison.Ordinal));
            }

            return Task.FromResult<IReadOnlyList<JobRunSnapshot>>(query.Take(limit).ToArray());
        }

        public Task<IReadOnlyList<JobRunSnapshot>> GetActiveRunsAsync(CancellationToken cancellationToken)
            => Task.FromResult(ActiveRuns);

        public Task<JobRunSnapshot?> GetRunAsync(Guid runId, CancellationToken cancellationToken)
            => Task.FromResult(Runs.TryGetValue(runId, out var run) ? run : null);

        public Task<JobRunSnapshot?> GetLastRunAsync(string kind, CancellationToken cancellationToken)
            => Task.FromResult(LastRuns.TryGetValue(kind, out var run) ? run : null);

        public Task<IReadOnlyDictionary<string, JobRunSnapshot>> GetLastRunsAsync(IEnumerable<string> kinds, CancellationToken cancellationToken)
        {
            var map = new Dictionary<string, JobRunSnapshot>(StringComparer.Ordinal);
            foreach (var kind in kinds)
            {
                if (kind is null)
                {
                    continue;
                }

                if (LastRuns.TryGetValue(kind, out var run) && run is not null)
                {
                    map[kind] = run;
                }
            }

            return Task.FromResult<IReadOnlyDictionary<string, JobRunSnapshot>>(map);
        }
    }
}
