#!/usr/bin/env python3
"""
Android ADB MCP Server

A Model Context Protocol (MCP) server for Android device automation via ADB.
Uses MCPMixin pattern for organized, extensible tool registration.

Features:
- Device management and multi-device support
- Screen capture and recording
- Input simulation (tap, swipe, key events, text)
- App launching and management
- Developer mode for advanced tools
"""

from typing import Any

from fastmcp import FastMCP
from fastmcp.contrib.mcp_mixin import mcp_resource, mcp_tool

from .config import get_config
from .mixins import (
    AppsMixin,
    DevicesMixin,
    FilesMixin,
    InputMixin,
    ScreenshotMixin,
    UIMixin,
)


class ADBServer(
    DevicesMixin, InputMixin, AppsMixin, ScreenshotMixin, UIMixin, FilesMixin
):
    """Android ADB MCP Server combining all functionality.

    Inherits from mixins:
    - DevicesMixin: Device listing, selection, info, logcat
    - InputMixin: Tap, swipe, keys, text input, clipboard
    - AppsMixin: App launching, URL opening, package management, intents
    - ScreenshotMixin: Screen capture, recording, display control
    - UIMixin: UI hierarchy inspection, element finding, text waiting
    - FilesMixin: File push/pull between host and device

    Developer mode enables additional tools for power users.
    """

    # === Configuration Tools ===

    @mcp_tool()
    async def config_status(self) -> dict[str, Any]:
        """Get current server configuration.

        Shows developer mode status and other settings.

        Returns:
            Current configuration values
        """
        config = get_config()
        return {
            "developer_mode": config.developer_mode,
            "auto_select_single_device": config.auto_select_single_device,
            "default_screenshot_dir": config.default_screenshot_dir,
            "current_device": self.get_current_device(),
        }

    @mcp_tool()
    async def config_set_developer_mode(self, enabled: bool) -> dict[str, Any]:
        """Enable or disable developer mode.

        Developer mode unlocks advanced tools:
        - Raw shell command execution
        - Package listing/installation/uninstallation
        - Screen recording and resolution changes
        - App data clearing
        - Long press gestures

        The setting persists across server restarts.

        Args:
            enabled: True to enable, False to disable

        Returns:
            Confirmation with new status
        """
        config = get_config()
        config.developer_mode = enabled

        return {
            "success": True,
            "developer_mode": enabled,
            "message": (
                "Developer mode enabled. Advanced tools are now available."
                if enabled
                else "Developer mode disabled. Using standard tools only."
            ),
        }

    @mcp_tool()
    async def config_set_screenshot_dir(self, directory: str | None) -> dict[str, Any]:
        """Set default directory for screenshots.

        Screenshots will be saved to this directory by default.
        Set to None to save to current working directory.

        Args:
            directory: Directory path, or None for current directory

        Returns:
            Confirmation
        """
        config = get_config()
        config.default_screenshot_dir = directory

        return {
            "success": True,
            "screenshot_dir": directory,
        }

    # === Help / Discovery ===

    @mcp_resource(uri="adb://help")
    async def resource_help(self) -> dict[str, Any]:
        """Resource: Server help and available tools overview."""
        config = get_config()

        tools = {
            "devices": [
                "devices_list - List connected devices",
                "devices_use - Set current device",
                "devices_current - Get current device info",
                "device_info - Battery, wifi, storage, system info",
            ],
            "input": [
                "input_tap - Tap at coordinates",
                "input_swipe - Swipe between points",
                "input_scroll_down / input_scroll_up - Scroll gestures",
                "input_back / input_home / input_recent_apps - Navigation",
                "input_key - Send any key event",
                "input_text - Type text",
                "clipboard_set - Set clipboard (handles special chars)",
            ],
            "apps": [
                "app_launch - Launch app by package name",
                "app_open_url - Open URL in browser",
                "app_close - Force stop an app",
                "app_current - Get focused app",
            ],
            "screen": [
                "screenshot - Capture screen",
                "screen_size / screen_density - Display info",
                "screen_on / screen_off - Wake/sleep display",
            ],
            "ui": [
                "ui_dump - Dump UI hierarchy (accessibility tree)",
                "ui_find_element - Find elements by text/id/class",
                "wait_for_text - Wait for text to appear",
                "wait_for_text_gone - Wait for text to disappear",
                "tap_text - Find element by text and tap it",
            ],
            "config": [
                "config_status - Show current settings",
                "config_set_developer_mode - Toggle developer tools",
                "config_set_screenshot_dir - Set screenshot output directory",
            ],
        }

        if config.developer_mode:
            tools["developer"] = [
                "shell_command - Execute any shell command",
                "input_long_press - Long press gesture",
                "app_list_packages - List installed packages",
                "app_install / app_uninstall - Install/remove apps",
                "app_clear_data - Clear app data",
                "activity_start - Start activity with intent",
                "broadcast_send - Send broadcast intent",
                "screen_record - Record screen video",
                "screen_set_size / screen_reset_size - Change resolution",
                "device_reboot - Reboot device",
                "logcat_capture / logcat_clear - Android logs",
                "file_push / file_pull - Transfer files",
                "file_list / file_delete / file_exists - File operations",
            ]

        return {
            "name": "Android ADB MCP Server",
            "developer_mode": config.developer_mode,
            "tools": tools,
            "tip": (
                "Use config_set_developer_mode(True) to unlock advanced tools"
                if not config.developer_mode
                else "Developer mode is active - all tools available"
            ),
        }


# Initialize FastMCP server
mcp = FastMCP(
    "mcadb",
    instructions="""Android ADB MCP Server for device automation.

Use devices_list() first to see connected devices.
If multiple devices are connected, use devices_use(device_id) to select one.

Common workflows:
1. Take screenshot: screenshot()
2. Tap on screen: input_tap(x, y)
3. Launch app: app_launch("com.android.chrome")
4. Open URL: app_open_url("https://example.com")
5. Navigate back: input_back()

Enable developer mode for advanced tools:
config_set_developer_mode(True)
""",
)

# Create server instance and register all tools
server = ADBServer()
server.register_all(mcp)


def main():
    """Main entry point for STDIO MCP server."""
    try:
        from importlib.metadata import version

        package_version = version("mcadb")
    except Exception:
        package_version = "0.3.1"

    print(f"📱 mcadb v{package_version}", flush=True)

    mcp.run()


if __name__ == "__main__":
    main()
