"""
AirClaw Patcher — auto-updates OpenClaw config to use local AirClaw server.
Supports JSON and JS configs. Always backs up before touching anything.
"""

import os
import re
import json
import shutil
from pathlib import Path

SEARCH_PATHS = [
    "~/.openclaw/config.json",
    "~/.openclaw/config.js",
    "~/.config/openclaw/config.json",
    "~/.config/openclaw/config.js",
    "~/openclaw/config.json",
    "~/openclaw/config.js",
    "~/AppData/Roaming/openclaw/config.json",
    "~/AppData/Roaming/openclaw/config.js",
    "/etc/openclaw/config.json",
    "./config.json",
    "./config.js",
]


def find_openclaw_config():
    for p in SEARCH_PATHS:
        path = Path(p).expanduser()
        if path.exists():
            return path
    home = Path.home()
    for name in ["config.json", "config.js"]:
        for m in home.glob(f"**/openclaw/{name}"):
            return m
        for m in home.glob(f"**/.openclaw/{name}"):
            return m
    return None


def backup(path):
    b = Path(str(path) + ".airclaw-backup")
    if not b.exists():
        shutil.copy2(path, b)
        print(f"[AirClaw] 💾 Backup: {b}")
    return b


def patch_json(path, host, port, model):
    content = path.read_text(encoding="utf-8").strip()
    config = json.loads(content) if content else {}
    config.setdefault("agent", {})
    config["agent"]["provider"] = "opencode"
    config["agent"].setdefault("opencode", {})
    config["agent"]["opencode"].update({"model": f"openai/{model}", "hostname": host, "port": port})
    backup(path)
    path.write_text(json.dumps(config, indent=2) + "\n", encoding="utf-8")
    print(f"[AirClaw] ✅ Patched: {path}")
    return True


def patch_js(path, host, port, model):
    content = path.read_text(encoding="utf-8")
    block = f"""  // AirClaw: local LLM — zero API cost
  agent: {{
    provider: 'opencode',
    opencode: {{
      model: 'openai/{model}',
      hostname: '{host}',
      port: {port},
    }},
  }},"""
    backup(path)
    # Replace existing AirClaw block
    existing = re.compile(r"//\s*AirClaw.*?agent\s*:\s*\{.*?\},", re.DOTALL)
    if existing.search(content):
        content = existing.sub(block, content, count=1)
    # Replace any agent block
    elif re.search(r"\bagent\s*:\s*\{", content):
        content = re.sub(r"\bagent\s*:\s*\{[^{}]*(?:\{[^{}]*\}[^{}]*)?\},?", block, content, count=1, flags=re.DOTALL)
    # Inject into module.exports
    elif re.search(r"module\.exports\s*=\s*\{", content):
        content = re.sub(
            r"(module\.exports\s*=\s*\{)([\s\S]*?)(\}\s*;?\s*$)",
            lambda m: m.group(1) + m.group(2).rstrip() + "\n\n" + block + "\n" + m.group(3),
            content
        )
    else:
        content += f"\n\nmodule.exports = {{\n{block}\n}};\n"
    path.write_text(content, encoding="utf-8")
    print(f"[AirClaw] ✅ Patched: {path}")
    return True


def patch_openclaw(host="127.0.0.1", port=4096, model="local-model", config_path=None):
    if config_path:
        path = Path(config_path).expanduser().resolve()
        if not path.exists():
            print(f"[AirClaw] ❌ Not found: {path}")
            return False
    else:
        print("[AirClaw] 🔍 Searching for OpenClaw config...")
        path = find_openclaw_config()

    if path is None:
        print("""
[AirClaw] ⚠️  Could not find OpenClaw config automatically.

Run: airclaw patch --config /path/to/config.json

Or add manually to your OpenClaw config:
  "agent": {
    "provider": "opencode",
    "opencode": { "model": "openai/local-model", "hostname": "127.0.0.1", "port": 4096 }
  }
""")
        return False

    print(f"[AirClaw] Found: {path}")
    if path.suffix == ".json":
        return patch_json(path, host, port, model)
    elif path.suffix == ".js":
        return patch_js(path, host, port, model)
    else:
        print(f"[AirClaw] ❌ Unknown format: {path.suffix}")
        return False


def restore_backup(config_path=None):
    path = Path(config_path).expanduser() if config_path else find_openclaw_config()
    if path is None:
        print("[AirClaw] ❌ Could not find config.")
        return False
    backup = Path(str(path) + ".airclaw-backup")
    if backup.exists():
        shutil.copy2(backup, path)
        print(f"[AirClaw] ✅ Restored from: {backup}")
        return True
    print(f"[AirClaw] ❌ No backup found: {backup}")
    return False
