using System.Text.RegularExpressions;
using ClaudeDo.Installer.Core;

namespace ClaudeDo.Installer.Checks;

/// <summary>
/// Static-only check per docs/explore-notes/installer-preflight.md §2: real auto-mode eligibility
/// (org/model/plan) has no cheap detectable signal, so this only confirms the CLI's argument
/// parser still recognizes "auto" as a --permission-mode choice. A warning, not a blocker — a
/// too-old CLI just degrades to acceptEdits/default with more prompts.
/// </summary>
public sealed class PermissionModeAutoCheck : IEnvironmentCheck
{
    public const string CheckId = "claude-permission-mode-auto";

    private static readonly Regex AutoWord = new(@"\bauto\b", RegexOptions.Compiled);
    private const int SearchWindow = 300;

    private readonly ClaudeCliLookup _lookup;

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

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

    public async Task<CheckResult> RunAsync(InstallContext ctx, CancellationToken ct)
    {
        var lookup = await _lookup.ResolveAsync(ctx, ct);
        if (lookup.Resolved is null)
        {
            return CheckResult.Unknown(Id, Severity, "checks.permissionModeAuto.title",
                "The claude CLI was not found — permission-mode support could not be checked.");
        }

        var (fileName, arguments) = ProcessCommand.For(lookup.Resolved, "--help");
        var (exitCode, output) = await _lookup.ProcessRunner.RunAsync(fileName, arguments, null, ct);

        if (exitCode != 0 || string.IsNullOrWhiteSpace(output))
        {
            return CheckResult.Unknown(Id, Severity, "checks.permissionModeAuto.title",
                "Could not determine whether --permission-mode auto is supported.");
        }

        if (AutoIsListed(output))
        {
            return CheckResult.Ok(Id, Severity, "checks.permissionModeAuto.title",
                "--permission-mode auto is recognized by this CLI.");
        }

        return CheckResult.Fail(Id, Severity, "checks.permissionModeAuto.title",
            "This claude CLI version does not list 'auto' as a --permission-mode choice.",
            "checks.permissionModeAuto.hint");
    }

    private static bool AutoIsListed(string helpOutput)
    {
        var index = helpOutput.IndexOf("--permission-mode", StringComparison.Ordinal);
        if (index < 0) return false;

        var windowEnd = Math.Min(helpOutput.Length, index + SearchWindow);
        return AutoWord.IsMatch(helpOutput[index..windowEnd]);
    }
}
