using ClaudeDo.Data.Models;
using ClaudeDo.Worker.Hub;
using ClaudeDo.Worker.Lifecycle;
using ClaudeDo.Worker.Tests.Infrastructure;
using Microsoft.Extensions.Logging.Abstractions;

namespace ClaudeDo.Worker.Tests.Lifecycle;

public sealed class LegacyWorktreeFolderRecoveryTests : IDisposable
{
    private readonly DbFixture _db = new();
    private readonly List<string> _tempDirs = new();

    public void Dispose()
    {
        _db.Dispose();
        foreach (var d in _tempDirs)
        {
            try { Directory.Delete(d, recursive: true); } catch { }
        }
    }

    private string MakeWorkingDir()
    {
        var dir = Path.Combine(Path.GetTempPath(), $"claudedo_legacy_wt_{Guid.NewGuid():N}");
        Directory.CreateDirectory(dir);
        _tempDirs.Add(dir);
        return dir;
    }

    [Fact]
    public void FindAffectedListNames_FolderInsideWorkingDir_ReturnsListName()
    {
        var wd = MakeWorkingDir();
        Directory.CreateDirectory(Path.Combine(wd, ".claudedo-worktrees"));
        var list = new ListEntity { Id = "1", Name = "Bandel.Hub", WorkingDir = wd, CreatedAt = DateTime.UtcNow };

        var affected = LegacyWorktreeFolderRecovery.FindAffectedListNames(new[] { list });

        Assert.Equal(new[] { "Bandel.Hub" }, affected);
    }

    [Fact]
    public void FindAffectedListNames_NoLegacyFolder_ReturnsEmpty()
    {
        var wd = MakeWorkingDir();
        var list = new ListEntity { Id = "1", Name = "Clean", WorkingDir = wd, CreatedAt = DateTime.UtcNow };

        var affected = LegacyWorktreeFolderRecovery.FindAffectedListNames(new[] { list });

        Assert.Empty(affected);
    }

    [Fact]
    public void FindAffectedListNames_NullWorkingDir_IsSkipped()
    {
        var list = new ListEntity { Id = "1", Name = "NoRepo", WorkingDir = null, CreatedAt = DateTime.UtcNow };

        var affected = LegacyWorktreeFolderRecovery.FindAffectedListNames(new[] { list });

        Assert.Empty(affected);
    }

    [Fact]
    public async Task StartAsync_NoLists_DoesNotThrow()
    {
        var hubContext = new CapturingHubContext();
        var sut = new LegacyWorktreeFolderRecovery(
            _db.CreateFactory(), new HubBroadcaster(hubContext), NullLogger<LegacyWorktreeFolderRecovery>.Instance);

        await sut.StartAsync(CancellationToken.None);
        await sut.StopAsync(CancellationToken.None);

        Assert.Contains(hubContext.Proxy.Calls, c =>
            c.Method == "OperationProgress" && (string)c.Args[0]! == "startup-recovery");
    }
}
