using ClaudeDo.Worker.Config;
using ClaudeDo.Worker.Tickets;

namespace ClaudeDo.Worker.Tests.Tickets;

public sealed class TicketSystemConfigTests : IDisposable
{
    private readonly string _dir = Path.Combine(Path.GetTempPath(), "cdo-tcfg-" + Guid.NewGuid().ToString("N"));

    private TicketSystemConfig Make(string? baseUrl, string? pat)
    {
        Directory.CreateDirectory(_dir);
        var store = new DpapiTokenStore(Path.Combine(_dir, "ticket.pat"));
        if (pat is not null) store.Save(pat);
        var worker = new WorkerConfig { TicketApiBaseUrl = baseUrl };
        return new TicketSystemConfig(worker, new TicketPatStore(store));
    }

    [Fact]
    public void Not_configured_without_base_url()
        => Assert.False(Make(null, "tsp_x").IsConfigured);

    [Fact]
    public void Not_configured_without_pat()
        => Assert.False(Make("http://api.local", null).IsConfigured);

    [Fact]
    public void Configured_with_both()
        => Assert.True(Make("http://api.local", "tsp_x").IsConfigured);

    [Fact]
    public void Blank_base_url_counts_as_missing()
        => Assert.False(Make("   ", "tsp_x").IsConfigured);

    [Fact]
    public void Base_url_trailing_slash_is_trimmed()
        => Assert.Equal("http://api.local", Make("http://api.local/", "tsp_x").BaseUrl);

    // Ein blanker Hostname ist das, was man in ein Feld namens "API base URL" tippt. Ohne Schema
    // ist das eine RELATIVE URI, und HttpClient lehnt sie mit InvalidOperationException ab —
    // genau daran ist die erste Einrichtung gescheitert.
    [Theory]
    [InlineData("bandelapis.fb-tuning.local", "http://bandelapis.fb-tuning.local")]
    [InlineData("bandelapis.fb-tuning.local/", "http://bandelapis.fb-tuning.local")]
    [InlineData("  bandelapis.fb-tuning.local  ", "http://bandelapis.fb-tuning.local")]
    [InlineData("api.local:8080", "http://api.local:8080")]
    public void Missing_scheme_defaults_to_http(string entered, string expected)
        => Assert.Equal(expected, Make(entered, "tsp_x").BaseUrl);

    [Theory]
    [InlineData("https://api.local")]
    [InlineData("http://api.local")]
    public void Explicit_scheme_is_left_alone(string entered)
        => Assert.Equal(entered, Make(entered, "tsp_x").BaseUrl);

    public void Dispose()
    {
        if (Directory.Exists(_dir)) Directory.Delete(_dir, recursive: true);
    }
}
