"""Public framework quality tests."""

from __future__ import annotations

from importlib import import_module

from click.testing import CliRunner

from logos_adk import Agent as RootAgent
from logos_adk import Agent as PublicAgent
from logos_adk.cli import cli
from logos_adk.config_loader import load_agent_config
from logos_adk.serve_security import load_api_keys_config
from logos_adk.version import (
    PRIVATE_MODULE_PREFIXES,
    PUBLIC_API_MODULES,
    PUBLIC_IMPORT_ROOT,
    STABILITY_POLICY,
    __version__,
)


def test_public_api_modules_are_importable_and_explicit():
    assert STABILITY_POLICY == "semver"
    assert PUBLIC_IMPORT_ROOT == "logos_adk"
    assert PRIVATE_MODULE_PREFIXES == ("logos_adk._", "logos_adk.__")
    for module_name in PUBLIC_API_MODULES:
        import_module(module_name)


def test_backward_compatible_root_and_public_imports_match_core_symbol():
    assert RootAgent is PublicAgent


def test_upgrade_fixtures_load_across_versions():
    legacy = load_agent_config("tests/fixtures/upgrade/v0_1_agent.yaml")
    stable = load_agent_config("tests/fixtures/upgrade/v0_2_agent.yaml")

    assert legacy.name == "legacy-bot"
    assert stable.security.output_max_length == 2048
    assert stable.scaling.task_queue.max_retries == 2


def test_release_notes_exist_for_current_version():
    result = CliRunner().invoke(cli, ["upgrade", "release-notes", "--version", __version__])

    assert result.exit_code == 0
    assert result.output.strip().endswith(f"{__version__}.md")


def test_upgrade_plan_and_checklist_commands_render():
    runner = CliRunner()

    plan = runner.invoke(
        cli,
        ["upgrade", "plan", "--from-version", "0.2.0", "--to-version", "0.3.0"],
    )
    checklist = runner.invoke(cli, ["upgrade", "checklist"])

    assert plan.exit_code == 0
    assert "0.2.0 -> 0.3.0" in plan.output
    assert "docs/upgrade-guide.md" in plan.output
    assert checklist.exit_code == 0
    assert "storage upgrade-check" in checklist.output


def test_project_generator_creates_template_files(tmp_path):
    destination = tmp_path / "generated"
    result = CliRunner().invoke(
        cli,
        ["project", "new", "single-agent-api", str(destination)],
    )

    assert result.exit_code == 0
    assert (destination / "app.py").exists()
    assert (destination / "agent.yaml").exists()


def test_rbac_role_expands_to_scopes():
    principals = load_api_keys_config(
        api_keys={
            "dev-key": {
                "name": "developer",
                "role": "developer",
                "workspaces": ["acme"],
            }
        }
    )

    principal = principals["dev-key"]
    assert principal.roles == {"developer"}
    assert principal.has_scope("agent:run") is True
    assert principal.has_scope("observability:read") is True
    assert principal.has_scope("state:write") is False
