from __future__ import annotations

from pathlib import Path

from cf_ontology import pipeline_state_runtime as runtime


class _Proc:
    def __init__(self, returncode: int = 0) -> None:
        self.returncode = returncode


def test_run_engine_does_not_set_direct_override_env_by_default(monkeypatch) -> None:
    captured: dict[str, object] = {}

    def _fake_run(cmd, check=False, env=None):  # noqa: ANN001, ANN202
        captured["cmd"] = cmd
        captured["check"] = check
        captured["env"] = env
        return _Proc(0)

    monkeypatch.setattr(runtime.subprocess, "run", _fake_run)
    code = runtime._run_engine(
        Path("demo.nq"),
        steps_paths=[],
        plugin_paths=[],
        exe="cf_pipeline_v2",
    )

    assert code == 0
    assert captured["check"] is False
    assert captured["env"] is None


def test_run_engine_applies_explicit_env_override(monkeypatch) -> None:
    captured: dict[str, object] = {}

    def _fake_run(cmd, check=False, env=None):  # noqa: ANN001, ANN202
        captured["cmd"] = cmd
        captured["check"] = check
        captured["env"] = env
        return _Proc(0)

    monkeypatch.setattr(runtime.subprocess, "run", _fake_run)
    code = runtime._run_engine(
        Path("demo.nq"),
        steps_paths=[],
        plugin_paths=[],
        exe="cf_pipeline_v2",
        env_overrides={"CF_ALLOW_DIRECT_ENGINE": "1"},
    )

    assert code == 0
    assert captured["check"] is False
    assert isinstance(captured["env"], dict)
    assert captured["env"]["CF_ALLOW_DIRECT_ENGINE"] == "1"


def test_run_engine_prepends_plugin_dirs_to_path(monkeypatch) -> None:
    captured: dict[str, object] = {}

    def _fake_run(cmd, check=False, env=None):  # noqa: ANN001, ANN202
        captured["cmd"] = cmd
        captured["check"] = check
        captured["env"] = env
        return _Proc(0)

    monkeypatch.setenv("PATH", "BASE_PATH")
    monkeypatch.setattr(runtime.subprocess, "run", _fake_run)
    code = runtime._run_engine(
        Path("demo.nq"),
        steps_paths=[],
        plugin_paths=["C:/plugins/a", "C:/plugins/b", "C:/plugins/a"],
        exe="cf_pipeline_v2",
    )

    assert code == 0
    assert captured["check"] is False
    assert isinstance(captured["env"], dict)
    expected_path = "C:/plugins/a" + runtime.os.pathsep + "C:/plugins/b" + runtime.os.pathsep + "BASE_PATH"
    assert captured["env"]["PATH"] == expected_path


def test_run_engine_uses_resolved_engine_when_exe_missing(monkeypatch) -> None:
    captured: dict[str, object] = {}

    def _fake_run(cmd, check=False, env=None):  # noqa: ANN001, ANN202
        captured["cmd"] = cmd
        captured["check"] = check
        captured["env"] = env
        return _Proc(0)

    monkeypatch.setattr(runtime, "_find_pipeline_exe", lambda: "resolved-engine")
    monkeypatch.setattr(runtime.subprocess, "run", _fake_run)
    code = runtime._run_engine(
        Path("demo.nq"),
        steps_paths=[],
        plugin_paths=[],
        exe=None,
    )

    assert code == 0
    assert isinstance(captured["cmd"], list)
    assert captured["cmd"][0] == "resolved-engine"
