using ClaudeDo.Worker.Usage.TokenTracker;
using ClaudeDo.Worker.Usage.TokenTracker.Interfaces;

namespace ClaudeDo.Worker.Tests.Usage.TokenTracker;

public sealed class FakeTokenTrackerClient : ITokenTrackerClient
{
    private readonly SemaphoreSlim _gate = new(0);

    public TokenTrackerProbe Probe { get; set; } = new(true, "1.2.3", true, "v22.1.0", null);
    public TokenTrackerRunResult ExportResult { get; set; } =
        new(true, TokenTrackerFixtures.SessionsJson, null);
    public TokenTrackerRunResult InstallResult { get; set; } = new(true, "added 1 package", null);

    public int ExportCalls;
    public int ProbeCalls;
    public int InstallCalls;
    public DateOnly? LastFrom;
    public DateOnly? LastTo;

    /// <summary>When true, <see cref="ExportAsync"/> blocks until <see cref="Release"/> is called.</summary>
    public bool BlockExport { get; set; }

    public void Release() => _gate.Release();

    public Task<TokenTrackerProbe> ProbeAsync(CancellationToken ct = default)
    {
        Interlocked.Increment(ref ProbeCalls);
        return Task.FromResult(Probe);
    }

    public async Task<TokenTrackerRunResult> ExportAsync(DateOnly from, DateOnly to, CancellationToken ct = default)
    {
        Interlocked.Increment(ref ExportCalls);
        LastFrom = from;
        LastTo = to;
        if (BlockExport) await _gate.WaitAsync(ct);
        return ExportResult;
    }

    public TokenTrackerDashboard DashboardResult { get; set; } = new(true, "http://127.0.0.1:7680/", null);
    public int DashboardCalls;

    public Task<TokenTrackerDashboard> StartDashboardAsync(CancellationToken ct = default)
    {
        Interlocked.Increment(ref DashboardCalls);
        return Task.FromResult(DashboardResult);
    }

    public Task<TokenTrackerRunResult> InstallAsync(IProgress<string>? output = null, CancellationToken ct = default)
    {
        Interlocked.Increment(ref InstallCalls);
        output?.Report("added 1 package");
        return Task.FromResult(InstallResult);
    }
}
