"""Tests for list_profiles.

This tool is the model's directory of what it may become: whatever it prints is
read as an offer. An admin-only profile listed here is both a disclosure (the
caller learns an id they were never meant to see) and a temptation the next
switch_profile call then has to refuse.
"""

import pytest

from navi.core.registry import ProfileRegistry
from navi.tools._internal.base import ToolContext, current_user_role
from navi.tools.list_profiles import ListProfilesTool
from tests.conftest_factory import make_profile


def _registry() -> ProfileRegistry:
    reg = ProfileRegistry()
    reg.register(make_profile("assistant", name="Assistant", description="Everyday helper"))
    reg.register(
        make_profile(
            "server_admin",
            name="Server Admin",
            description="Remote ops on the owner's hosts",
            is_admin_only=True,
        )
    )
    reg.register(make_profile("hidden_role", name="Dispatcher", is_hidden=True))
    return reg


def _tool() -> ListProfilesTool:
    return ListProfilesTool(_registry())


def _ctx(role: str) -> ToolContext:
    return ToolContext(user_id="u1", session_id="s1", user_role=role)


@pytest.mark.asyncio
async def test_a_user_sees_only_the_profiles_they_may_use():
    result = await _tool().execute({}, ctx=_ctx("user"))

    assert result.success is True
    assert "assistant" in result.output
    assert "server_admin" not in result.output
    assert "hidden_role" not in result.output


@pytest.mark.asyncio
async def test_an_admin_sees_the_admin_only_profiles():
    result = await _tool().execute({}, ctx=_ctx("admin"))

    assert result.success is True
    assert "assistant" in result.output
    assert "server_admin" in result.output
    assert "hidden_role" not in result.output  # hidden stays hidden, even for admin


@pytest.mark.asyncio
async def test_naming_an_admin_only_profile_is_refused_without_echoing_it():
    result = await _tool().execute({"profile_id": "server_admin"}, ctx=_ctx("user"))

    assert result.success is False
    assert result.error.startswith("Profile 'server_admin' requires admin access")
    assert "assistant" in result.error


@pytest.mark.asyncio
async def test_an_admin_may_look_up_an_admin_only_profile():
    result = await _tool().execute({"profile_id": "server_admin"}, ctx=_ctx("admin"))

    assert result.success is True
    assert "Server Admin" in result.output


@pytest.mark.asyncio
async def test_the_role_comes_from_the_contextvar_when_ctx_is_absent():
    token = current_user_role.set("user")
    try:
        result = await _tool().execute({})
    finally:
        current_user_role.reset(token)

    assert "server_admin" not in result.output
