# retoor <retoor@molodetz.nl>

from devplacepy.services.devii.actions.catalog import PLATFORM_CATALOG
from devplacepy.services.devii.actions.dispatcher import (
    CONFIRM_REQUIRED,
    MUTATING_METHODS,
)

BY_NAME = PLATFORM_CATALOG.by_name()


def _records_mutation(name: str) -> bool:
    action = BY_NAME[name]
    return action.method in MUTATING_METHODS and not action.is_read_only


def test_post_query_tools_are_read_only_so_the_plan_gate_keeps_their_rows():
    for name in ("db_query", "db_design_query"):
        assert BY_NAME[name].is_read_only is True
        assert _records_mutation(name) is False


def test_db_get_tools_are_read_only():
    for name in ("db_list_tables", "db_table_schema", "db_list_rows", "db_get_row"):
        assert BY_NAME[name].is_read_only is True
        assert _records_mutation(name) is False


def test_db_has_no_mutation_tools():
    for name in ("db_insert_row", "db_update_row", "db_delete_row", "db_restore_row"):
        assert name not in BY_NAME
        assert name not in CONFIRM_REQUIRED


def test_seo_report_is_public_read_only_http_action():
    action = BY_NAME["seo_report"]
    assert action.handler == "http"
    assert action.method == "GET"
    assert action.path == "/tools/seo/{uid}/report"
    assert action.requires_auth is False
    assert action.is_read_only is True
    assert _records_mutation("seo_report") is False
    assert "seo_report" not in CONFIRM_REQUIRED
    names = {p.name for p in action.params}
    assert "uid" in names


def test_ui_prompt_is_local_interaction_action():
    from devplacepy.services.devii.registry import CATALOG

    by_name = CATALOG.by_name()
    action = by_name["ui_prompt"]
    assert action.handler == "interaction"
    assert action.requires_auth is False
    names = {p.name for p in action.params}
    assert "title" in names
    assert "widgets" in names
    assert "ui_cancel" in by_name
    assert "ui_notify" in by_name


def test_block_mute_tools_exist_as_http_actions():
    expected = {
        "block_user": "/block/{username}",
        "unblock_user": "/block/unblock/{username}",
        "mute_user": "/mute/{username}",
        "unmute_user": "/mute/unmute/{username}",
    }
    for name, path in expected.items():
        action = BY_NAME[name]
        assert action.handler == "http"
        assert action.method == "POST"
        assert action.path == path
        assert action.requires_auth is True
        assert action.requires_admin is False
        assert "username" in {p.name for p in action.params}


def test_block_mute_tools_visible_to_authenticated_user():
    schemas = PLATFORM_CATALOG.tool_schemas_for(authenticated=True, is_admin=False)
    names = {s["function"]["name"] for s in schemas}
    for name in ("block_user", "unblock_user", "mute_user", "unmute_user"):
        assert name in names


def test_block_mute_tools_hidden_from_guests():
    schemas = PLATFORM_CATALOG.tool_schemas_for(authenticated=False)
    names = {s["function"]["name"] for s in schemas}
    for name in ("block_user", "unblock_user", "mute_user", "unmute_user"):
        assert name not in names


def test_game_actions_registered_with_correct_auth():
    public = {"game_state", "game_leaderboard", "game_view_farm"}
    auth = {
        "game_plant",
        "game_harvest",
        "game_buy_plot",
        "game_upgrade_ci",
        "game_water",
        "game_fertilize",
        "game_daily",
        "game_upgrade_perk",
        "game_claim_quest",
        "game_prestige",
    }
    for name in public | auth:
        assert name in BY_NAME, name
    assert BY_NAME["game_state"].requires_auth is True
    assert BY_NAME["game_leaderboard"].requires_auth is False
    assert BY_NAME["game_view_farm"].requires_auth is False
    for name in auth:
        assert BY_NAME[name].requires_auth is True, name


def test_game_read_actions_are_read_only():
    for name in ("game_state", "game_leaderboard", "game_view_farm"):
        assert BY_NAME[name].is_read_only is True


def test_scheduling_tools_need_an_account_but_not_an_administrator():
    from devplacepy.services.devii.registry import CATALOG

    by_name = CATALOG.by_name()
    for name in ("create_task", "update_task", "run_task_now"):
        action = by_name[name]
        assert action.requires_auth is True
        assert action.requires_admin is False


def test_scheduling_tools_are_offered_to_a_member():
    from devplacepy.services.devii.registry import CATALOG

    member = {
        s["function"]["name"]
        for s in CATALOG.tool_schemas_for(authenticated=True, is_admin=False)
    }
    for name in ("create_task", "update_task", "run_task_now", "list_tasks"):
        assert name in member


def test_scheduling_tools_are_hidden_from_guests():
    from devplacepy.services.devii.registry import CATALOG

    guest = {
        s["function"]["name"] for s in CATALOG.tool_schemas_for(authenticated=False)
    }
    for name in ("create_task", "update_task", "run_task_now"):
        assert name not in guest
