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

namespace ClaudeDo.Installer.Checks;

/// <summary>Without the claude CLI, no task can ever run — blocking.</summary>
public sealed class ClaudeCliCheck : IEnvironmentCheck
{
    public const string CheckId = "claude-cli";

    private readonly ClaudeCliLookup _lookup;

    public ClaudeCliCheck(ClaudeCliLookup lookup)
    {
        _lookup = lookup;
    }

    public string Id => CheckId;
    public CheckSeverity Severity => CheckSeverity.Error;

    public async Task<CheckResult> RunAsync(InstallContext ctx, CancellationToken ct)
    {
        var lookup = await _lookup.ResolveAsync(ctx, ct);

        if (lookup.Resolved is null)
        {
            var searched = string.Join(", ", SearchedLocations());
            return CheckResult.Fail(Id, Severity, "checks.claudeCli.title",
                $"'{ctx.ClaudeBin}' was not found on PATH. Searched: {searched}.",
                "checks.claudeCli.hint");
        }

        if (lookup.ExitCode != 0)
        {
            return CheckResult.Fail(Id, Severity, "checks.claudeCli.title",
                $"'{lookup.Resolved.Path}' exited with code {lookup.ExitCode}.",
                "checks.claudeCli.hint", detail: lookup.Output);
        }

        var version = lookup.ParsedVersion?.ToString() ?? lookup.Output.Trim();
        var detail = lookup.Resolved.IsShim
            ? "Resolved via a shim (.cmd/.bat/.ps1), not a native .exe."
            : null;
        return CheckResult.Ok(Id, Severity, "checks.claudeCli.title", $"{lookup.Resolved.Path} — {version}", detail);
    }

    private IEnumerable<string> SearchedLocations()
    {
        var pathVar = _lookup.PathOverride ?? System.Environment.GetEnvironmentVariable("PATH") ?? "";
        var pathEntries = pathVar.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
        return pathEntries.Concat(ExecutableResolver.FallbackDirectories());
    }
}
