import { describe, expect, it } from "vitest";
import { PermissionKey, SystemRole, type PermissionKey as PermissionKeyValue } from "@capakraken/shared";
import { getAvailableAssistantTools } from "../router/assistant-tool-policy.js";
import { TOOL_DEFINITIONS } from "../router/assistant-tools.js";

function getToolNames(
  permissions: PermissionKeyValue[],
  userRole: SystemRole = SystemRole.ADMIN,
) {
  return getAvailableAssistantTools(new Set(permissions), userRole).map((tool) => tool.function.name);
}

describe("assistant tool policy", () => {
  it("hides advanced tools unless the dedicated assistant permission is granted", () => {
    const withoutAdvanced = getToolNames([
      PermissionKey.VIEW_PLANNING,
      PermissionKey.VIEW_COSTS,
    ]);
    const withAdvanced = getToolNames([
      PermissionKey.VIEW_PLANNING,
      PermissionKey.VIEW_COSTS,
      PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
    ]);

    expect(withoutAdvanced).not.toContain("find_best_project_resource");
    expect(withAdvanced).toContain("find_best_project_resource");
    expect(withAdvanced).toContain("get_chargeability_report");
    expect(withAdvanced).toContain("get_resource_computation_graph");
    expect(withAdvanced).toContain("get_project_computation_graph");
  });

  it("keeps user self-service tools available to plain authenticated users", () => {
    const userNames = getToolNames([], SystemRole.USER);

    expect(userNames).toContain("get_current_user");
    expect(userNames).toContain("get_dashboard_layout");
    expect(userNames).toContain("save_dashboard_layout");
    expect(userNames).toContain("get_favorite_project_ids");
    expect(userNames).toContain("toggle_favorite_project");
    expect(userNames).toContain("get_column_preferences");
    expect(userNames).toContain("set_column_preferences");
    expect(userNames).toContain("get_mfa_status");
    expect(userNames).toContain("list_notifications");
    expect(userNames).toContain("get_unread_notification_count");
    expect(userNames).toContain("list_tasks");
    expect(userNames).toContain("get_task_counts");
    expect(userNames).toContain("create_reminder");
    expect(userNames).toContain("list_reminders");
    expect(userNames).toContain("update_reminder");
    expect(userNames).toContain("delete_reminder");
  });

  it("keeps admin-only user tools hidden from non-admin roles", () => {
    const adminNames = getToolNames([], SystemRole.ADMIN);
    const managerNames = getToolNames([], SystemRole.MANAGER);
    const userNames = getToolNames([], SystemRole.USER);

    expect(adminNames).toContain("list_users");
    expect(adminNames).toContain("get_active_user_count");
    expect(adminNames).toContain("create_user");
    expect(adminNames).toContain("set_user_password");
    expect(adminNames).toContain("update_user_role");
    expect(adminNames).toContain("update_user_name");
    expect(adminNames).toContain("link_user_resource");
    expect(adminNames).toContain("auto_link_users_by_email");
    expect(adminNames).toContain("set_user_permissions");
    expect(adminNames).toContain("reset_user_permissions");
    expect(adminNames).toContain("get_effective_user_permissions");
    expect(adminNames).toContain("disable_user_totp");

    expect(managerNames).not.toContain("list_users");
    expect(managerNames).not.toContain("create_user");
    expect(managerNames).not.toContain("set_user_permissions");
    expect(managerNames).not.toContain("disable_user_totp");
    expect(userNames).not.toContain("list_users");
    expect(userNames).not.toContain("get_active_user_count");
    expect(userNames).not.toContain("create_user");
    expect(userNames).not.toContain("set_user_password");
    expect(userNames).not.toContain("update_user_role");
    expect(userNames).not.toContain("update_user_name");
    expect(userNames).not.toContain("link_user_resource");
    expect(userNames).not.toContain("auto_link_users_by_email");
    expect(userNames).not.toContain("set_user_permissions");
    expect(userNames).not.toContain("reset_user_permissions");
    expect(userNames).not.toContain("get_effective_user_permissions");
    expect(userNames).not.toContain("disable_user_totp");
  });

  it("keeps assignable users and manager notification lifecycle tools behind manager/admin role", () => {
    const managerNames = getToolNames([], SystemRole.MANAGER);
    const adminNames = getToolNames([], SystemRole.ADMIN);
    const userNames = getToolNames([], SystemRole.USER);

    expect(managerNames).toContain("list_assignable_users");
    expect(managerNames).toContain("create_notification");
    expect(managerNames).toContain("create_task_for_user");
    expect(managerNames).toContain("assign_task");
    expect(managerNames).toContain("send_broadcast");
    expect(managerNames).toContain("list_broadcasts");
    expect(managerNames).toContain("get_broadcast_detail");
    expect(adminNames).toContain("list_assignable_users");
    expect(adminNames).toContain("create_task_for_user");
    expect(adminNames).toContain("send_broadcast");
    expect(userNames).not.toContain("list_assignable_users");
    expect(userNames).not.toContain("create_notification");
    expect(userNames).not.toContain("create_task_for_user");
    expect(userNames).not.toContain("assign_task");
    expect(userNames).not.toContain("send_broadcast");
    expect(userNames).not.toContain("list_broadcasts");
    expect(userNames).not.toContain("get_broadcast_detail");
  });

  it("continues to hide cost-aware advanced tools when viewCosts is missing", () => {
    const names = getToolNames([PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS]);

    expect(names).not.toContain("find_best_project_resource");
    expect(names).not.toContain("get_chargeability_report");
    expect(names).not.toContain("get_resource_computation_graph");
    expect(names).not.toContain("get_project_computation_graph");
  });

  it("keeps controller-grade readmodels hidden from plain users while allowing controller roles", () => {
    const controllerNames = getToolNames([
      PermissionKey.VIEW_COSTS,
      PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
    ], SystemRole.CONTROLLER);
    const userNames = getToolNames([
      PermissionKey.VIEW_COSTS,
      PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
    ], SystemRole.USER);

    expect(controllerNames).toContain("query_change_history");
    expect(controllerNames).toContain("get_entity_timeline");
    expect(controllerNames).toContain("search_by_skill");
    expect(controllerNames).toContain("export_resources_csv");
    expect(controllerNames).toContain("export_projects_csv");
    expect(controllerNames).toContain("list_audit_log_entries");
    expect(controllerNames).toContain("get_audit_log_entry");
    expect(controllerNames).toContain("get_audit_log_timeline");
    expect(controllerNames).toContain("get_audit_activity_summary");
    expect(controllerNames).toContain("get_chargeability_report");
    expect(controllerNames).toContain("get_resource_computation_graph");
    expect(controllerNames).toContain("get_project_computation_graph");
    expect(userNames).not.toContain("query_change_history");
    expect(userNames).not.toContain("get_entity_timeline");
    expect(userNames).not.toContain("search_by_skill");
    expect(userNames).not.toContain("export_resources_csv");
    expect(userNames).not.toContain("export_projects_csv");
    expect(userNames).not.toContain("list_audit_log_entries");
    expect(userNames).not.toContain("get_audit_log_entry");
    expect(userNames).not.toContain("get_audit_log_timeline");
    expect(userNames).not.toContain("get_audit_activity_summary");
    expect(userNames).not.toContain("get_chargeability_report");
    expect(userNames).not.toContain("get_resource_computation_graph");
    expect(userNames).not.toContain("get_project_computation_graph");
  });

  it("keeps entity-scoped comment tools available to plain authenticated users", () => {
    const userNames = getToolNames([], SystemRole.USER);

    expect(userNames).toContain("list_comments");
    expect(userNames).toContain("create_comment");
    expect(userNames).toContain("resolve_comment");
  });

  it("keeps planning read tools behind the explicit planning permission", () => {
    const userWithoutPlanning = getToolNames([], SystemRole.USER);
    const userWithPlanning = getToolNames([PermissionKey.VIEW_PLANNING], SystemRole.USER);

    expect(userWithoutPlanning).not.toContain("list_allocations");
    expect(userWithoutPlanning).not.toContain("list_demands");
    expect(userWithoutPlanning).not.toContain("list_blueprints");
    expect(userWithoutPlanning).not.toContain("get_blueprint");
    expect(userWithoutPlanning).not.toContain("list_clients");
    expect(userWithoutPlanning).not.toContain("list_roles");
    expect(userWithoutPlanning).not.toContain("list_management_levels");
    expect(userWithoutPlanning).not.toContain("list_utilization_categories");
    expect(userWithoutPlanning).not.toContain("check_resource_availability");
    expect(userWithoutPlanning).not.toContain("find_capacity");
    expect(userWithoutPlanning).not.toContain("get_staffing_suggestions");
    expect(userWithoutPlanning).not.toContain("find_best_project_resource");
    expect(userWithPlanning).toContain("list_allocations");
    expect(userWithPlanning).toContain("list_demands");
    expect(userWithPlanning).toContain("list_blueprints");
    expect(userWithPlanning).toContain("get_blueprint");
    expect(userWithPlanning).toContain("list_clients");
    expect(userWithPlanning).toContain("list_roles");
    expect(userWithPlanning).toContain("list_management_levels");
    expect(userWithPlanning).toContain("list_utilization_categories");
    expect(userWithPlanning).toContain("check_resource_availability");
    expect(userWithPlanning).toContain("find_capacity");
    expect(userWithPlanning).not.toContain("get_staffing_suggestions");
    expect(userWithPlanning).not.toContain("find_best_project_resource");
  });

  it("keeps cost-aware staffing assistant tools behind cost and advanced gates", () => {
    const planningOnly = getToolNames([PermissionKey.VIEW_PLANNING], SystemRole.USER);
    const planningAndCosts = getToolNames([
      PermissionKey.VIEW_PLANNING,
      PermissionKey.VIEW_COSTS,
    ], SystemRole.USER);
    const planningCostsAndAdvanced = getToolNames([
      PermissionKey.VIEW_PLANNING,
      PermissionKey.VIEW_COSTS,
      PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
    ], SystemRole.USER);

    expect(planningOnly).not.toContain("get_staffing_suggestions");
    expect(planningOnly).not.toContain("find_best_project_resource");
    expect(planningAndCosts).toContain("get_staffing_suggestions");
    expect(planningAndCosts).not.toContain("find_best_project_resource");
    expect(planningCostsAndAdvanced).toContain("get_staffing_suggestions");
    expect(planningCostsAndAdvanced).toContain("find_best_project_resource");
  });

  it("keeps controller-only project and dashboard reads hidden from plain users", () => {
    const controllerNames = getToolNames([
      PermissionKey.VIEW_COSTS,
      PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
    ], SystemRole.CONTROLLER);
    const userNames = getToolNames([
      PermissionKey.VIEW_COSTS,
      PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
      PermissionKey.VIEW_PLANNING,
    ], SystemRole.USER);

    expect(controllerNames).toContain("search_projects");
    expect(controllerNames).toContain("get_project");
    expect(controllerNames).toContain("get_statistics");
    expect(controllerNames).toContain("get_dashboard_detail");
    expect(controllerNames).toContain("get_skill_gaps");
    expect(controllerNames).toContain("get_project_health");
    expect(controllerNames).toContain("get_budget_forecast");
    expect(controllerNames).toContain("get_budget_status");
    expect(controllerNames).toContain("get_shoring_ratio");
    expect(userNames).not.toContain("search_projects");
    expect(userNames).not.toContain("get_project");
    expect(userNames).not.toContain("get_statistics");
    expect(userNames).not.toContain("get_dashboard_detail");
    expect(userNames).not.toContain("get_skill_gaps");
    expect(userNames).not.toContain("get_project_health");
    expect(userNames).not.toContain("get_budget_forecast");
    expect(userNames).not.toContain("get_budget_status");
    expect(userNames).not.toContain("get_shoring_ratio");
  });

  it("keeps legacy controller-only analysis and report tools hidden from plain users", () => {
    const controllerNames = getToolNames([
      PermissionKey.VIEW_COSTS,
      PermissionKey.VIEW_PLANNING,
    ], SystemRole.CONTROLLER);
    const userNames = getToolNames([
      PermissionKey.VIEW_COSTS,
      PermissionKey.VIEW_PLANNING,
    ], SystemRole.USER);

    expect(controllerNames).toContain("detect_anomalies");
    expect(controllerNames).toContain("get_insights_summary");
    expect(controllerNames).toContain("run_report");
    expect(controllerNames).toContain("lookup_rate");
    expect(controllerNames).toContain("simulate_scenario");
    expect(controllerNames).toContain("generate_project_narrative");
    expect(controllerNames).toContain("list_rate_cards");
    expect(controllerNames).toContain("resolve_rate");
    expect(userNames).not.toContain("detect_anomalies");
    expect(userNames).not.toContain("get_insights_summary");
    expect(userNames).not.toContain("run_report");
    expect(userNames).not.toContain("lookup_rate");
    expect(userNames).not.toContain("simulate_scenario");
    expect(userNames).not.toContain("generate_project_narrative");
    expect(userNames).not.toContain("list_rate_cards");
    expect(userNames).not.toContain("resolve_rate");
  });

  it("keeps cost-sensitive legacy rate tools hidden without viewCosts", () => {
    const controllerWithoutCosts = getToolNames([], SystemRole.CONTROLLER);
    const controllerWithCosts = getToolNames([PermissionKey.VIEW_COSTS], SystemRole.CONTROLLER);

    expect(controllerWithoutCosts).not.toContain("list_rate_cards");
    expect(controllerWithoutCosts).not.toContain("resolve_rate");
    expect(controllerWithCosts).toContain("list_rate_cards");
    expect(controllerWithCosts).toContain("resolve_rate");
  });

  it("requires both controller role and advanced assistant access for timeline detail tools", () => {
    const controllerWithAdvanced = getToolNames([
      PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
    ], SystemRole.CONTROLLER);
    const controllerWithoutAdvanced = getToolNames([], SystemRole.CONTROLLER);
    const userWithAdvanced = getToolNames([
      PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
    ], SystemRole.USER);

    expect(controllerWithAdvanced).toContain("get_timeline_entries_view");
    expect(controllerWithAdvanced).toContain("get_timeline_holiday_overlays");
    expect(controllerWithAdvanced).toContain("get_project_timeline_context");
    expect(controllerWithAdvanced).toContain("preview_project_shift");
    expect(controllerWithoutAdvanced).not.toContain("get_timeline_entries_view");
    expect(controllerWithoutAdvanced).not.toContain("get_timeline_holiday_overlays");
    expect(controllerWithoutAdvanced).not.toContain("get_project_timeline_context");
    expect(controllerWithoutAdvanced).not.toContain("preview_project_shift");
    expect(userWithAdvanced).not.toContain("get_timeline_entries_view");
    expect(userWithAdvanced).not.toContain("get_timeline_holiday_overlays");
    expect(userWithAdvanced).not.toContain("get_project_timeline_context");
    expect(userWithAdvanced).not.toContain("preview_project_shift");
  });

  it("exposes self-service timeline tools to authenticated users without advanced assistant access", () => {
    const userNames = getToolNames([], SystemRole.USER);
    const viewerNames = getToolNames([], SystemRole.VIEWER);
    const controllerNames = getToolNames([], SystemRole.CONTROLLER);

    expect(userNames).toContain("get_my_timeline_entries_view");
    expect(userNames).toContain("get_my_timeline_holiday_overlays");
    expect(viewerNames).toContain("get_my_timeline_entries_view");
    expect(viewerNames).toContain("get_my_timeline_holiday_overlays");
    expect(controllerNames).toContain("get_my_timeline_entries_view");
    expect(controllerNames).toContain("get_my_timeline_holiday_overlays");
  });

  it("keeps timeline write parity tools behind manager/admin role, manageAllocations, and advanced assistant access", () => {
    const managerNames = getToolNames([
      PermissionKey.MANAGE_ALLOCATIONS,
      PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
    ], SystemRole.MANAGER);
    const userNames = getToolNames([
      PermissionKey.MANAGE_ALLOCATIONS,
      PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
    ], SystemRole.USER);
    const missingAdvancedNames = getToolNames([
      PermissionKey.MANAGE_ALLOCATIONS,
    ], SystemRole.MANAGER);

    expect(managerNames).toContain("update_timeline_allocation_inline");
    expect(managerNames).toContain("apply_timeline_project_shift");
    expect(managerNames).toContain("quick_assign_timeline_resource");
    expect(managerNames).toContain("batch_quick_assign_timeline_resources");
    expect(managerNames).toContain("batch_shift_timeline_allocations");
    expect(userNames).not.toContain("update_timeline_allocation_inline");
    expect(userNames).not.toContain("apply_timeline_project_shift");
    expect(userNames).not.toContain("quick_assign_timeline_resource");
    expect(userNames).not.toContain("batch_quick_assign_timeline_resources");
    expect(userNames).not.toContain("batch_shift_timeline_allocations");
    expect(missingAdvancedNames).not.toContain("update_timeline_allocation_inline");
    expect(missingAdvancedNames).not.toContain("quick_assign_timeline_resource");
  });

  it("keeps estimate lifecycle mutations behind manager/admin role and their router permissions", () => {
    const managerProjectNames = getToolNames([PermissionKey.MANAGE_PROJECTS], SystemRole.MANAGER);
    const managerAllocationNames = getToolNames([PermissionKey.MANAGE_ALLOCATIONS], SystemRole.MANAGER);
    const userProjectNames = getToolNames([PermissionKey.MANAGE_PROJECTS], SystemRole.USER);

    expect(managerProjectNames).toContain("create_estimate");
    expect(managerProjectNames).toContain("clone_estimate");
    expect(managerProjectNames).toContain("update_estimate_draft");
    expect(managerProjectNames).toContain("submit_estimate_version");
    expect(managerProjectNames).toContain("approve_estimate_version");
    expect(managerProjectNames).toContain("create_estimate_revision");
    expect(managerProjectNames).toContain("create_estimate_export");
    expect(managerProjectNames).toContain("generate_estimate_weekly_phasing");
    expect(managerProjectNames).toContain("update_estimate_commercial_terms");
    expect(managerProjectNames).not.toContain("create_estimate_planning_handoff");
    expect(managerAllocationNames).toContain("create_estimate_planning_handoff");
    expect(managerAllocationNames).not.toContain("create_estimate");
    expect(userProjectNames).not.toContain("create_estimate");
    expect(userProjectNames).not.toContain("clone_estimate");
    expect(userProjectNames).not.toContain("update_estimate_draft");
    expect(userProjectNames).not.toContain("submit_estimate_version");
    expect(userProjectNames).not.toContain("approve_estimate_version");
    expect(userProjectNames).not.toContain("create_estimate_revision");
    expect(userProjectNames).not.toContain("create_estimate_export");
    expect(userProjectNames).not.toContain("generate_estimate_weekly_phasing");
    expect(userProjectNames).not.toContain("update_estimate_commercial_terms");
    expect(userProjectNames).not.toContain("create_estimate_planning_handoff");
  });

  it("keeps estimate read tools aligned to controller/manager/admin visibility and cost requirements", () => {
    const controllerNames = getToolNames([PermissionKey.VIEW_COSTS], SystemRole.CONTROLLER);
    const controllerWithoutCosts = getToolNames([], SystemRole.CONTROLLER);
    const managerNames = getToolNames([PermissionKey.VIEW_COSTS], SystemRole.MANAGER);
    const managerWithoutCosts = getToolNames([], SystemRole.MANAGER);
    const userNames = getToolNames([PermissionKey.VIEW_COSTS], SystemRole.USER);

    expect(controllerNames).toContain("search_estimates");
    expect(controllerNames).toContain("get_estimate_detail");
    expect(controllerNames).toContain("list_estimate_versions");
    expect(controllerNames).toContain("get_estimate_version_snapshot");
    expect(controllerNames).toContain("get_estimate_weekly_phasing");
    expect(controllerNames).toContain("get_estimate_commercial_terms");
    expect(controllerWithoutCosts).toContain("search_estimates");
    expect(controllerWithoutCosts).not.toContain("get_estimate_detail");
    expect(controllerWithoutCosts).toContain("list_estimate_versions");
    expect(controllerWithoutCosts).not.toContain("get_estimate_version_snapshot");
    expect(controllerWithoutCosts).toContain("get_estimate_weekly_phasing");
    expect(controllerWithoutCosts).toContain("get_estimate_commercial_terms");
    expect(managerNames).toContain("search_estimates");
    expect(managerNames).toContain("get_estimate_detail");
    expect(managerNames).toContain("list_estimate_versions");
    expect(managerNames).toContain("get_estimate_version_snapshot");
    expect(managerNames).toContain("get_estimate_weekly_phasing");
    expect(managerNames).toContain("get_estimate_commercial_terms");
    expect(managerWithoutCosts).toContain("search_estimates");
    expect(managerWithoutCosts).toContain("list_estimate_versions");
    expect(managerWithoutCosts).not.toContain("get_estimate_version_snapshot");
    expect(userNames).not.toContain("search_estimates");
    expect(userNames).not.toContain("get_estimate_detail");
    expect(userNames).not.toContain("list_estimate_versions");
    expect(userNames).not.toContain("get_estimate_version_snapshot");
    expect(userNames).not.toContain("get_estimate_weekly_phasing");
    expect(userNames).not.toContain("get_estimate_commercial_terms");
  });

  it("keeps import/dispo parity tools aligned to router roles and permissions", () => {
    const managerNames = getToolNames([PermissionKey.IMPORT_DATA], SystemRole.MANAGER);
    const controllerNames = getToolNames([], SystemRole.CONTROLLER);
    const adminNames = getToolNames([], SystemRole.ADMIN);
    const userNames = getToolNames([PermissionKey.IMPORT_DATA], SystemRole.USER);

    expect(managerNames).toContain("import_csv_data");
    expect(controllerNames).toContain("export_resources_csv");
    expect(controllerNames).toContain("export_projects_csv");
    expect(adminNames).toContain("list_dispo_import_batches");
    expect(adminNames).toContain("get_dispo_import_batch");
    expect(adminNames).toContain("stage_dispo_import_batch");
    expect(adminNames).toContain("validate_dispo_import_batch");
    expect(adminNames).toContain("cancel_dispo_import_batch");
    expect(adminNames).toContain("list_dispo_staged_resources");
    expect(adminNames).toContain("list_dispo_staged_projects");
    expect(adminNames).toContain("list_dispo_staged_assignments");
    expect(adminNames).toContain("list_dispo_staged_vacations");
    expect(adminNames).toContain("list_dispo_staged_unresolved_records");
    expect(adminNames).toContain("resolve_dispo_staged_record");
    expect(adminNames).toContain("commit_dispo_import_batch");
    expect(userNames).not.toContain("import_csv_data");
    expect(userNames).not.toContain("export_resources_csv");
    expect(userNames).not.toContain("export_projects_csv");
    expect(userNames).not.toContain("list_dispo_import_batches");
    expect(userNames).not.toContain("get_dispo_import_batch");
    expect(userNames).not.toContain("stage_dispo_import_batch");
    expect(userNames).not.toContain("validate_dispo_import_batch");
    expect(userNames).not.toContain("list_dispo_staged_resources");
    expect(userNames).not.toContain("commit_dispo_import_batch");
  });

  it("keeps settings and webhook admin tools hidden while preserving protected parity tools", () => {
    const adminNames = getToolNames([], SystemRole.ADMIN);
    const managerNames = getToolNames([], SystemRole.MANAGER);
    const userNames = getToolNames([], SystemRole.USER);

    expect(adminNames).toContain("get_system_settings");
    expect(adminNames).toContain("update_system_settings");
    expect(adminNames).toContain("clear_stored_runtime_secrets");
    expect(adminNames).toContain("test_ai_connection");
    expect(adminNames).toContain("test_smtp_connection");
    expect(adminNames).toContain("test_gemini_connection");
    expect(adminNames).toContain("list_system_role_configs");
    expect(adminNames).toContain("update_system_role_config");
    expect(adminNames).toContain("list_webhooks");
    expect(adminNames).toContain("get_webhook");
    expect(adminNames).toContain("create_webhook");
    expect(adminNames).toContain("update_webhook");
    expect(adminNames).toContain("delete_webhook");
    expect(adminNames).toContain("test_webhook");
    expect(adminNames).toContain("get_ai_configured");

    expect(managerNames).not.toContain("get_system_settings");
    expect(managerNames).not.toContain("update_system_settings");
    expect(managerNames).not.toContain("clear_stored_runtime_secrets");
    expect(managerNames).not.toContain("test_ai_connection");
    expect(managerNames).not.toContain("get_ai_configured");
    expect(managerNames).not.toContain("list_system_role_configs");
    expect(managerNames).not.toContain("update_system_role_config");
    expect(managerNames).not.toContain("list_webhooks");
    expect(managerNames).not.toContain("create_webhook");

    expect(userNames).not.toContain("get_system_settings");
    expect(userNames).not.toContain("update_system_settings");
    expect(userNames).not.toContain("clear_stored_runtime_secrets");
    expect(userNames).not.toContain("test_ai_connection");
    expect(userNames).not.toContain("get_ai_configured");
    expect(userNames).not.toContain("list_system_role_configs");
    expect(userNames).not.toContain("update_system_role_config");
    expect(userNames).not.toContain("list_webhooks");
    expect(userNames).not.toContain("create_webhook");
  });

  it("keeps client deletion admin-only while still allowing manager client maintenance", () => {
    const adminNames = getToolNames([], SystemRole.ADMIN);
    const managerNames = getToolNames([], SystemRole.MANAGER);
    const userNames = getToolNames([], SystemRole.USER);

    expect(adminNames).toContain("create_client");
    expect(adminNames).toContain("update_client");
    expect(adminNames).toContain("delete_client");
    expect(managerNames).toContain("create_client");
    expect(managerNames).toContain("update_client");
    expect(managerNames).not.toContain("delete_client");
    expect(userNames).not.toContain("create_client");
    expect(userNames).not.toContain("update_client");
    expect(userNames).not.toContain("delete_client");
  });

  it("keeps holiday calendar catalog tools admin-only while leaving preview available", () => {
    const adminNames = getToolNames([], SystemRole.ADMIN);
    const managerNames = getToolNames([], SystemRole.MANAGER);
    const userNames = getToolNames([], SystemRole.USER);

    expect(adminNames).toContain("list_holiday_calendars");
    expect(adminNames).toContain("get_holiday_calendar");
    expect(adminNames).toContain("preview_resolved_holiday_calendar");
    expect(adminNames).toContain("create_holiday_calendar");
    expect(managerNames).not.toContain("list_holiday_calendars");
    expect(managerNames).not.toContain("get_holiday_calendar");
    expect(managerNames).toContain("preview_resolved_holiday_calendar");
    expect(userNames).not.toContain("list_holiday_calendars");
    expect(userNames).not.toContain("get_holiday_calendar");
    expect(userNames).toContain("preview_resolved_holiday_calendar");
    expect(managerNames).not.toContain("create_holiday_calendar");
    expect(managerNames).not.toContain("update_holiday_calendar");
    expect(managerNames).not.toContain("delete_holiday_calendar");
    expect(managerNames).not.toContain("create_holiday_calendar_entry");
    expect(managerNames).not.toContain("update_holiday_calendar_entry");
    expect(managerNames).not.toContain("delete_holiday_calendar_entry");
  });

  it("keeps country and metro-city mutation tools admin-only while leaving read tools available", () => {
    const adminNames = getToolNames([], SystemRole.ADMIN);
    const managerNames = getToolNames([], SystemRole.MANAGER);
    const userNames = getToolNames([], SystemRole.USER);
    const userWithResourceOverview = getToolNames([PermissionKey.VIEW_ALL_RESOURCES], SystemRole.USER);
    const userWithManagedResources = getToolNames([PermissionKey.MANAGE_RESOURCES], SystemRole.USER);

    expect(adminNames).toContain("list_countries");
    expect(adminNames).toContain("create_country");
    expect(adminNames).toContain("update_country");
    expect(adminNames).toContain("create_metro_city");
    expect(adminNames).toContain("update_metro_city");
    expect(adminNames).toContain("delete_metro_city");
    expect(managerNames).toContain("list_countries");
    expect(managerNames).not.toContain("create_country");
    expect(managerNames).not.toContain("update_country");
    expect(managerNames).not.toContain("create_metro_city");
    expect(managerNames).not.toContain("update_metro_city");
    expect(managerNames).not.toContain("delete_metro_city");
    expect(userNames).not.toContain("search_resources");
    expect(userNames).not.toContain("get_country");
    expect(userNames).not.toContain("list_org_units");
    expect(userWithResourceOverview).toContain("search_resources");
    expect(userWithResourceOverview).toContain("get_country");
    expect(userWithResourceOverview).toContain("list_org_units");
    expect(userWithManagedResources).toContain("search_resources");
    expect(userWithManagedResources).toContain("get_country");
    expect(userWithManagedResources).toContain("list_org_units");
  });

  it("attaches explicit access metadata to legacy monolithic tools with restricted visibility", () => {
    const toolAccess = new Map(
      TOOL_DEFINITIONS.map((tool) => [tool.function.name, tool.access]),
    );

    expect(toolAccess.get("run_report")).toEqual({
      allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER],
    });
    expect(toolAccess.get("simulate_scenario")).toEqual({
      allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER],
    });
    expect(toolAccess.get("detect_anomalies")).toEqual({
      allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER],
    });
    expect(toolAccess.get("get_insights_summary")).toEqual({
      allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER],
    });
    expect(toolAccess.get("lookup_rate")).toEqual({
      allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER],
    });
    expect(toolAccess.get("list_rate_cards")).toEqual({
      allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER],
      requiresCostView: true,
    });
    expect(toolAccess.get("resolve_rate")).toEqual({
      allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER],
      requiresCostView: true,
    });
    expect(toolAccess.get("import_csv_data")).toEqual({
      requiredPermissions: [PermissionKey.IMPORT_DATA],
      allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER],
    });
  });

  it("aligns assistant tool visibility with router role and permission rules", () => {
    const managerWithRolePermission = getToolNames(
      [PermissionKey.MANAGE_ROLES],
      SystemRole.MANAGER,
    );
    const managerWithoutRolePermission = getToolNames([], SystemRole.MANAGER);

    expect(managerWithRolePermission).toContain("create_role");
    expect(managerWithRolePermission).toContain("update_role");
    expect(managerWithRolePermission).toContain("delete_role");
    expect(managerWithRolePermission).toContain("create_client");
    expect(managerWithRolePermission).toContain("update_client");
    expect(managerWithRolePermission).not.toContain("create_org_unit");
    expect(managerWithRolePermission).not.toContain("update_org_unit");

    expect(managerWithoutRolePermission).not.toContain("create_role");
    expect(managerWithoutRolePermission).not.toContain("update_role");
    expect(managerWithoutRolePermission).not.toContain("delete_role");
    expect(managerWithoutRolePermission).toContain("create_client");
    expect(managerWithoutRolePermission).toContain("update_client");

    const adminWithRolePermission = getToolNames(
      [PermissionKey.MANAGE_ROLES],
      SystemRole.ADMIN,
    );
    expect(adminWithRolePermission).toContain("create_org_unit");
    expect(adminWithRolePermission).toContain("update_org_unit");

    const standardUserTools = getToolNames([], SystemRole.USER);
    expect(standardUserTools).toContain("get_vacation_balance");
    expect(standardUserTools).toContain("create_vacation");
    expect(standardUserTools).toContain("cancel_vacation");
    expect(standardUserTools).not.toContain("approve_vacation");
    expect(standardUserTools).not.toContain("reject_vacation");
    expect(standardUserTools).not.toContain("set_entitlement");

    const managerVacationTools = getToolNames([], SystemRole.MANAGER);
    expect(managerVacationTools).toContain("approve_vacation");
    expect(managerVacationTools).toContain("reject_vacation");
    expect(managerVacationTools).toContain("set_entitlement");
  });
});
