from __future__ import annotations

import contextlib
import importlib.util
import io
import sys
import unittest
from pathlib import Path

REPO_DIR = Path(__file__).resolve().parents[1]
SPEC = importlib.util.spec_from_file_location(
    "openbao_credential_change_appliers",
    REPO_DIR / "scripts/openbao-apply-credential-change-appliers.py",
)
appliers = importlib.util.module_from_spec(SPEC)
assert SPEC.loader is not None
sys.modules[SPEC.name] = appliers
SPEC.loader.exec_module(appliers)


class CredentialChangeApplierSetupTests(unittest.TestCase):
    def test_selected_appliers_all_is_stable(self) -> None:
        selected = appliers.selected_appliers("all")
        self.assertEqual(
            [item["token_role"] for item in selected],
            ["credential-change-nonprod-applier", "credential-change-prod-applier"],
        )

    def test_role_args_are_bounded(self) -> None:
        args = appliers.role_args(appliers.APPLIERS["prod"])
        self.assertIn("auth/token/roles/credential-change-prod-applier", args)
        self.assertIn("allowed_policies=credential-change-prod-applier", args)
        self.assertIn("disallowed_policies=root,platform-admin", args)
        self.assertIn("token_no_default_policy=true", args)
        self.assertIn("token_type=service", args)

    def test_dry_run_applies_policy_role_and_readback(self) -> None:
        runner = appliers.BaoRunner(
            kubectl="kubectl",
            namespace="openbao",
            release="openbao",
            dry_run=True,
            use_token_helper=False,
            token=None,
        )
        output = io.StringIO()
        with contextlib.redirect_stdout(output):
            appliers.apply_applier(
                runner,
                appliers.APPLIERS["nonprod"],
                REPO_DIR / "openbao/policies",
            )
        rendered = output.getvalue()
        self.assertIn(
            "DRY-RUN: bao policy write credential-change-nonprod-applier",
            rendered,
        )
        self.assertIn(
            "DRY-RUN: bao write auth/token/roles/credential-change-nonprod-applier",
            rendered,
        )
        self.assertIn(
            "DRY-RUN: bao read auth/token/roles/credential-change-nonprod-applier",
            rendered,
        )


if __name__ == "__main__":
    unittest.main()
