"""Tests for stack-IR kyverno-json policies (REQ-299, v1.25).

Tests the 3 policies in adapters/kyverno-json/policies/stack-ir/:
require-tagging-standard, forbid-public-ingress, require-encryption-by-
default. Uses the passing + failing fixtures. Skips when kj is absent.
"""

import json
import os
import sys
from pathlib import Path

import pytest

sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

import importlib.util
_ENGINE_PATH = Path(__file__).resolve().parent.parent / "adapters" / "kyverno-json" / "kyverno_json_engine.py"
_spec = importlib.util.spec_from_file_location("kyverno_json_engine", _ENGINE_PATH)
_mod = importlib.util.module_from_spec(_spec)
_spec.loader.exec_module(_mod)
KyvernoJsonEngine = _mod.KyvernoJsonEngine

POLICY_DIR = Path(__file__).resolve().parent.parent / "adapters" / "kyverno-json" / "policies" / "stack-ir"
FIXTURES = Path(__file__).resolve().parent / "fixtures" / "stack_ir"


def _kj_installed() -> bool:
    return _mod._which_kj() is not None


@pytest.fixture(autouse=True)
def _require_kj():
    if not _kj_installed():
        pytest.skip("kj not installed (scripts/install-kyverno-json.sh)")


def _load(name):
    with open(FIXTURES / name, "r", encoding="utf-8") as fh:
        return json.load(fh)


class TestPassingFixture:
    def test_passing_fixture_all_pass(self):
        eng = KyvernoJsonEngine()
        out = eng.evaluate(_load("passing.json"), POLICY_DIR, "cid-pass")
        assert isinstance(out, list)
        assert len(out) >= 1
        # No fail results on the passing fixture.
        fails = [p for p in out if p["result"] == "fail"]
        assert fails == [], f"expected no fails on passing fixture, got: {fails}"


class TestFailingFixture:
    def test_failing_fixture_has_fails(self):
        eng = KyvernoJsonEngine()
        out = eng.evaluate(_load("failing.json"), POLICY_DIR, "cid-fail")
        fails = [p for p in out if p["result"] == "fail"]
        assert len(fails) >= 1, "expected at least one fail on the failing fixture"


class TestPolicyFilesExist:
    def test_three_policies_present(self):
        files = sorted(os.listdir(POLICY_DIR))
        assert "require-tagging-standard.json" in files
        assert "forbid-public-ingress.json" in files
        assert "require-encryption-by-default.json" in files


class TestPolicyValidity:
    def test_policies_are_valid_json(self):
        for f in os.listdir(POLICY_DIR):
            if f.endswith(".json"):
                with open(POLICY_DIR / f, "r", encoding="utf-8") as fh:
                    data = json.load(fh)
                assert data["apiVersion"] == "json.kyverno.io/v1alpha1"
                assert data["kind"] == "ValidatingPolicy"
                assert "nova.cloudinit.dev/severity" in data["metadata"]["annotations"]

    def test_policy_names_match_filenames(self):
        for f in os.listdir(POLICY_DIR):
            if f.endswith(".json"):
                with open(POLICY_DIR / f, "r", encoding="utf-8") as fh:
                    data = json.load(fh)
                expected = f.rsplit(".", 1)[0]
                assert data["metadata"]["name"] == expected