"""Developer utility tools for toggling artifacts and managing system properties."""

from mcp.server.fastmcp import FastMCP

from servicenow_mcp.auth import BasicAuthProvider
from servicenow_mcp.client import ServiceNowClient
from servicenow_mcp.config import Settings
from servicenow_mcp.policy import (
    MASK_VALUE,
    check_table_access,
    is_sensitive_field,
    write_blocked_reason,
)
from servicenow_mcp.tools.metadata import ARTIFACT_TABLES
from servicenow_mcp.utils import (
    ServiceNowQuery,
    format_response,
    generate_correlation_id,
    safe_tool_call,
    validate_identifier,
)


def register_tools(mcp: FastMCP, settings: Settings, auth_provider: BasicAuthProvider) -> None:
    """Register developer utility tools on the MCP server."""

    @mcp.tool()
    async def dev_toggle(artifact_type: str, sys_id: str, active: bool) -> str:
        """Toggle the active field on a ServiceNow artifact (business rule, script include, etc.).

        Args:
            artifact_type: The type of artifact (e.g. 'business_rule', 'script_include').
            sys_id: The sys_id of the artifact record.
            active: Whether to set the artifact active (true) or inactive (false).
        """
        correlation_id = generate_correlation_id()

        async def _run() -> str:
            # Resolve artifact type to table name
            table = ARTIFACT_TABLES.get(artifact_type)
            if table is None:
                return format_response(
                    data=None,
                    correlation_id=correlation_id,
                    status="error",
                    error=f"Unknown artifact type: '{artifact_type}'. "
                    f"Valid types: {', '.join(sorted(ARTIFACT_TABLES.keys()))}",
                )

            check_table_access(table)
            validate_identifier(sys_id)

            # Write gate
            reason = write_blocked_reason(table, settings)
            if reason:
                return format_response(
                    data=None,
                    correlation_id=correlation_id,
                    status="error",
                    error=reason,
                )

            async with ServiceNowClient(settings, auth_provider) as client:
                # Read current state
                current = await client.get_record(table, sys_id)
                old_active = current.get("active", "unknown")

                # Update active field
                updated = await client.update_record(table, sys_id, {"active": str(active).lower()})
                new_active = updated.get("active", "unknown")

            return format_response(
                data={
                    "sys_id": sys_id,
                    "artifact_type": artifact_type,
                    "table": table,
                    "old_active": old_active,
                    "new_active": new_active,
                },
                correlation_id=correlation_id,
            )

        return await safe_tool_call(_run, correlation_id)

    @mcp.tool()
    async def dev_set_property(name: str, value: str) -> str:
        """Set a ServiceNow system property value. Returns the old value.

        Args:
            name: The property name (e.g. 'glide.ui.session_timeout').
            value: The new value to set.
        """
        correlation_id = generate_correlation_id()

        async def _run() -> str:
            # Write gate
            check_table_access("sys_properties")
            reason = write_blocked_reason("sys_properties", settings)
            if reason:
                return format_response(
                    data=None,
                    correlation_id=correlation_id,
                    status="error",
                    error=reason,
                )

            async with ServiceNowClient(settings, auth_provider) as client:
                # Find the property by name
                result = await client.query_records(
                    "sys_properties",
                    ServiceNowQuery().equals("name", name).build(),
                    limit=1,
                )
                records = result["records"]
                if not records:
                    return format_response(
                        data=None,
                        correlation_id=correlation_id,
                        status="error",
                        error=f"Property '{name}' not found",
                    )

                prop = records[0]
                prop_sys_id = prop["sys_id"]
                old_value = prop.get("value", "")

                # Update the property value
                updated = await client.update_record("sys_properties", prop_sys_id, {"value": value})
                new_value = updated.get("value", value)

            # Mask values for sensitive property names
            display_old = MASK_VALUE if is_sensitive_field(name) else old_value
            display_new = MASK_VALUE if is_sensitive_field(name) else new_value

            return format_response(
                data={
                    "name": name,
                    "sys_id": prop_sys_id,
                    "old_value": display_old,
                    "new_value": display_new,
                },
                correlation_id=correlation_id,
            )

        return await safe_tool_call(_run, correlation_id)
