using System.IO;
using ClaudeDo.Installer.Core;

namespace ClaudeDo.Installer.Tests;

public class AutostartShortcutTests
{
    private static string TempDir()
    {
        var dir = Path.Combine(Path.GetTempPath(), "cdautostart-" + Guid.NewGuid().ToString("N"));
        Directory.CreateDirectory(dir);
        return dir;
    }

    [Fact]
    public void Install_creates_lnk_with_expected_name()
    {
        var startup = TempDir();
        var workerDir = TempDir();
        try
        {
            var workerExe = Path.Combine(workerDir, "ClaudeDo.Worker.exe");
            File.WriteAllText(workerExe, "");

            var created = AutostartShortcut.Install(startup, workerExe);

            Assert.True(created);
            Assert.True(File.Exists(Path.Combine(startup, AutostartShortcut.FileName)));
        }
        finally { Directory.Delete(startup, true); Directory.Delete(workerDir, true); }
    }

    [Fact]
    public void Install_is_noop_when_shortcut_already_targets_same_exe()
    {
        var startup = TempDir();
        var workerDir = TempDir();
        try
        {
            var workerExe = Path.Combine(workerDir, "ClaudeDo.Worker.exe");
            File.WriteAllText(workerExe, "");
            AutostartShortcut.Install(startup, workerExe);
            var writtenAt = File.GetLastWriteTimeUtc(Path.Combine(startup, AutostartShortcut.FileName));

            var createdAgain = AutostartShortcut.Install(startup, workerExe);

            Assert.False(createdAgain);
            Assert.Equal(writtenAt, File.GetLastWriteTimeUtc(Path.Combine(startup, AutostartShortcut.FileName)));
        }
        finally { Directory.Delete(startup, true); Directory.Delete(workerDir, true); }
    }

    [Fact]
    public void Install_rewrites_shortcut_when_target_changed()
    {
        var startup = TempDir();
        var workerDir = TempDir();
        try
        {
            var oldExe = Path.Combine(workerDir, "old", "ClaudeDo.Worker.exe");
            Directory.CreateDirectory(Path.GetDirectoryName(oldExe)!);
            File.WriteAllText(oldExe, "");
            AutostartShortcut.Install(startup, oldExe);

            var newExe = Path.Combine(workerDir, "new", "ClaudeDo.Worker.exe");
            Directory.CreateDirectory(Path.GetDirectoryName(newExe)!);
            File.WriteAllText(newExe, "");

            var created = AutostartShortcut.Install(startup, newExe);

            Assert.True(created);
            Assert.Equal(newExe, ShortcutFactory.TryGetTarget(Path.Combine(startup, AutostartShortcut.FileName)));
        }
        finally { Directory.Delete(startup, true); Directory.Delete(workerDir, true); }
    }

    [Fact]
    public void Remove_deletes_existing_lnk()
    {
        var startup = TempDir();
        var workerDir = TempDir();
        try
        {
            var workerExe = Path.Combine(workerDir, "ClaudeDo.Worker.exe");
            File.WriteAllText(workerExe, "");
            AutostartShortcut.Install(startup, workerExe);

            AutostartShortcut.Remove(startup);

            Assert.False(File.Exists(Path.Combine(startup, AutostartShortcut.FileName)));
        }
        finally { Directory.Delete(startup, true); Directory.Delete(workerDir, true); }
    }

    [Fact]
    public void Remove_is_noop_when_missing()
    {
        var startup = TempDir();
        try { AutostartShortcut.Remove(startup); } // must not throw
        finally { Directory.Delete(startup, true); }
    }
}
