using ClaudeDo.Installer.Core;

namespace ClaudeDo.Installer.Steps;

public sealed class StopServiceStep : IInstallStep
{
    public const string ServiceName = "ClaudeDoWorker";

    public string Name => "Stop Worker Service";

    public async Task<StepResult> ExecuteAsync(InstallContext ctx, IProgress<string> progress, CancellationToken ct)
    {
        progress.Report($"Stopping {ServiceName} (if running)...");

        // sc.exe query -> returns non-zero if the service does not exist; that's fine.
        var (queryExit, queryOutput) = await ProcessRunner.RunAsync("sc.exe", $"query {ServiceName}", null, progress, ct);
        if (queryExit != 0)
        {
            progress.Report("Service is not registered — nothing to stop.");
            return StepResult.Ok();
        }

        if (queryOutput.Contains("STOPPED", StringComparison.OrdinalIgnoreCase))
        {
            progress.Report("Service is already stopped.");
            return StepResult.Ok();
        }

        var (stopExit, _) = await ProcessRunner.RunAsync("sc.exe", $"stop {ServiceName}", null, progress, ct);
        // 1062 = ERROR_SERVICE_NOT_ACTIVE — registered but not running, treat as already stopped.
        if (stopExit == 1062)
        {
            progress.Report("Service was registered but not running.");
            return StepResult.Ok();
        }
        if (stopExit != 0)
            return StepResult.Fail($"sc.exe stop failed with exit code {stopExit}");

        // Poll until stopped or timeout (up to 30s).
        for (var i = 0; i < 30; i++)
        {
            ct.ThrowIfCancellationRequested();
            await Task.Delay(1000, ct);
            var (e, o) = await ProcessRunner.RunAsync("sc.exe", $"query {ServiceName}", null, progress, ct);
            if (e != 0 || o.Contains("STOPPED", StringComparison.OrdinalIgnoreCase))
            {
                progress.Report("Service stopped.");
                return StepResult.Ok();
            }
        }

        return StepResult.Fail("Service did not stop within 30 seconds.");
    }
}
