from __future__ import annotations

from iac.runbook.cel_eval import CelEngine, _to_python
from iac.runbook.expr import default_ctx
from iac.runbook.model import Book, BookMeta
from iac.runbook.sensitive import redact_vars_map, sensitive_values
from iac.runbook.template import TemplateEngine, _filter_default, _filter_replace


def test_cel_engine_empty_and_type_conversions() -> None:
    cel = CelEngine.default()
    assert cel.eval("", {"inputs": {}, "steps": {}, "run": {}}) is None
    assert isinstance(cel.eval("1.5", {}), float)
    assert cel.eval("[1,2,3]", {}) == [1, 2, 3]
    assert cel.eval('{"a": 1}', {}) == {"a": 1}


def test_cel_to_python_fallback_exception_path() -> None:
    cyc = []
    cyc.append(cyc)
    out = _to_python(cyc)
    assert out is cyc


def test_template_and_expr_misc_paths() -> None:
    t = TemplateEngine.default()
    assert t.render_str("${HOME}", vars_map={}, env_map={"HOME": "/tmp"}) == "/tmp"
    assert t.render_obj(None, vars_map={}, env_map={}) is None
    assert t.render_obj(
        ["${X}", {"k": "${Y}"}], vars_map={}, env_map={"X": "a", "Y": "b"}
    ) == ["a", {"k": "b"}]
    assert _filter_default(None, "x") == "x"
    assert _filter_replace(None, "a", "b") == ""
    ctx = default_ctx()
    assert "os" in ctx


def test_sensitive_helpers_non_empty_keys() -> None:
    book = Book(
        meta=BookMeta(name="x"),
        vars={},
        inputs={},
        requires=[],
        outputs={},
        hooks={},
        sensitive=["secret"],
        steps=[],
    )
    vals = sensitive_values(book, vars_map={"secret": "top"})
    assert vals == ["top"]
    redacted = redact_vars_map(book, {"secret": "top", "ok": "1"})
    assert redacted["secret"] == "********"
    assert redacted["ok"] == "1"
