"""Diagnostic checks: Roo Code / Cline configuration."""
from __future__ import annotations

import asyncio
import json
import shutil
import subprocess
from pathlib import Path
from typing import Any


_SETTINGS_CANDIDATES = [
    Path.home() / ".local" / "share" / "code-server" / "User" / "settings.json",
    Path("/app/vscode-user-data/settings.json"),
]

_SETTINGS_NOT_FOUND_DOCKER_MISSING = "settings.json not found and docker not on PATH"


def _read_settings_json(settings_file: Path) -> dict[str, Any] | None:
    try:
        return json.loads(settings_file.read_text())
    except Exception:
        return None


def _apply_roo_settings(result: dict[str, Any], data: dict[str, Any]) -> None:
    result["details"].pop("error", None)
    result["api_provider"] = data.get("roo-cline.apiProvider")
    result["base_url"] = data.get("roo-cline.openAiBaseUrl")
    result["configured"] = (
        result["api_provider"] == "openai" and bool(result["base_url"]) and bool(data.get("roo-cline.openAiApiKey"))
    )
    result["details"]["model_id"] = data.get("roo-cline.openAiModelId")
    result["details"]["custom_modes_count"] = len(data.get("roo-cline.customModes", []))
    result["details"]["has_api_key"] = bool(data.get("roo-cline.openAiApiKey"))
    modes = data.get("roo-cline.modeApiConfigs", {})
    result["details"]["mode_configs"] = list(modes.keys()) if modes else []
    mcp = data.get("roo-cline.mcpServers", {})
    result["details"]["mcp_servers"] = list(mcp.keys()) if mcp else []
    result["details"]["workspace_trust_disabled"] = data.get("security.workspace.trust.enabled") is False
    result["details"]["color_theme"] = data.get("workbench.colorTheme")


async def _load_settings_from_docker(errors: list[str]) -> dict[str, Any] | None:
    docker_bin = shutil.which("docker")
    if not docker_bin:
        errors.append(_SETTINGS_NOT_FOUND_DOCKER_MISSING)
        return None

    try:
        proc = await asyncio.to_thread(
            subprocess.run,
            [
                "docker",
                "exec",
                "proxym-vscode",
                "cat",
                "/home/coder/.local/share/code-server/User/settings.json",
            ],
            capture_output=True,
            text=True,
            timeout=10,
        )
        if proc.returncode == 0 and proc.stdout.strip():
            return json.loads(proc.stdout)
        errors.append(proc.stderr.strip() or f"docker exec exited with {proc.returncode}")
    except Exception as e:
        errors.append(str(e))

    return None


async def check_roo_cline_config() -> dict[str, Any]:
    """Check if Roo Code is configured in VS Code settings."""
    result = {
        "service": "roo_cline",
        "settings_file_exists": False,
        "configured": False,
        "api_provider": None,
        "base_url": None,
        "details": {},
    }

    data: dict[str, Any] | None = None
    errors: list[str] = []

    for settings_file in _SETTINGS_CANDIDATES:
        try:
            exists = settings_file.exists()
        except PermissionError:
            errors.append(f"[Errno 13] Permission denied: '{settings_file}'")
            continue

        if not exists:
            continue

        result["settings_file_exists"] = True
        result["details"]["settings_source"] = str(settings_file)
        data = _read_settings_json(settings_file)
        if data is not None:
            break
        errors.append(f"{settings_file}: invalid JSON or unreadable")

    if data is None:
        data = await _load_settings_from_docker(errors)

    if data is None and not result["settings_file_exists"] and _SETTINGS_NOT_FOUND_DOCKER_MISSING in errors:
        result["status"] = "skipped"
        result["details"]["skipped"] = _SETTINGS_NOT_FOUND_DOCKER_MISSING
        return result

    if data is None and errors:
        result["details"]["error"] = errors[-1]

    if data is not None:
        if "settings_source" not in result["details"]:
            result["details"]["settings_source"] = "docker://proxym-vscode:/home/coder/.local/share/code-server/User/settings.json"
        _apply_roo_settings(result, data)

    return result
