from __future__ import annotations

import os

from oncecheck.engine import installers


def test_missing_engines_shape(monkeypatch):
    monkeypatch.setattr(installers, "available_engines", lambda: {"codeql": False, "semgrep": True})
    assert installers.missing_engines() == ["codeql"]


def test_install_commands_include_semgrep():
    cmds = installers._install_commands("semgrep")
    flat = " ".join(" ".join(c) for c in cmds)
    assert "semgrep" in flat


def test_install_commands_include_codeql():
    cmds = installers._install_commands("codeql")
    flat = " ".join(" ".join(c) for c in cmds)
    assert "codeql" in flat or flat == ""


def test_windows_codeql_commands_include_noninteractive_flags(monkeypatch):
    monkeypatch.setattr(installers.platform, "system", lambda: "Windows")
    monkeypatch.setattr(installers.shutil, "which", lambda name: "x" if name in {"choco", "winget"} else None)
    cmds = installers._install_commands("codeql")
    flat_cmds = [" ".join(c) for c in cmds]
    assert any("--no-progress" in cmd for cmd in flat_cmds)
    assert any("--accept-source-agreements" in cmd for cmd in flat_cmds)
    assert any("--accept-package-agreements" in cmd for cmd in flat_cmds)


def test_wait_for_engine_retries_until_available(monkeypatch):
    states = iter([{"semgrep": False, "codeql": False}, {"semgrep": True, "codeql": False}])
    monkeypatch.setattr(installers, "available_engines", lambda: next(states))
    monkeypatch.setattr(installers.time, "sleep", lambda _x: None)
    assert installers._wait_for_engine("semgrep", timeout_seconds=3, interval_seconds=1) is True


def test_install_hints_windows_non_admin(monkeypatch):
    monkeypatch.setattr(installers.platform, "system", lambda: "Windows")
    monkeypatch.setattr(installers, "_is_windows_admin", lambda: False)
    hints = installers._install_hints(installed=["semgrep"], failed=["codeql"])
    joined = " ".join(hints)
    assert "Administrator" in joined
    assert "restart the terminal" in joined


def test_augment_path_for_engine_adds_directory(monkeypatch):
    monkeypatch.setattr(installers.platform, "system", lambda: "Windows")
    monkeypatch.setattr(installers, "_candidate_windows_bin_dirs", lambda: [r"C:\Tools"])
    monkeypatch.setattr(installers.os.path, "exists", lambda p: p.replace("/", "\\") == r"C:\Tools\semgrep.exe")
    monkeypatch.setenv("PATH", r"C:\Windows\System32")
    ok = installers._augment_path_for_engine("semgrep")
    assert ok is True
    assert os.environ["PATH"].startswith(r"C:\Tools")
