#!/usr/bin/env python3
from __future__ import annotations

import argparse
import json
import os
import shutil
import sys
from datetime import datetime
from pathlib import Path

from common import (
    default_openclaw_config_path,
    find_agent_entry,
    load_openclaw_config,
    resolve_existing_agent_entry,
)

ALLOWED_BACKUP_STATUSES = {"UPDATABLE", "SAME_VERSION_REINSTALL"}


def backup_md_files(workspace_path: Path, backup_dir: Path) -> list[str]:
    copied_files: list[str] = []
    if not workspace_path.is_dir():
        return copied_files

    backup_dir.mkdir(parents=True, exist_ok=True)
    for file_path in sorted(workspace_path.iterdir()):
        if file_path.is_file() and file_path.suffix == ".md":
            shutil.copy2(file_path, backup_dir / file_path.name)
            copied_files.append(file_path.name)
    return copied_files


def backup_agent(
    agent_id: str,
    status: str,
    config_path: Path,
    backup_root: Path,
    *,
    openclaw_id: str | None = None,
    workspace: str | None = None,
) -> dict[str, object]:
    if status not in ALLOWED_BACKUP_STATUSES:
        raise ValueError(
            "当前状态不允许执行备份。"
            f"仅当状态为 {', '.join(sorted(ALLOWED_BACKUP_STATUSES))} 时才能备份，当前状态: {status}"
        )

    openclaw = load_openclaw_config(config_path)
    agent_entry = None
    if isinstance(openclaw_id, str) and openclaw_id.strip():
        agent_entry = find_agent_entry(openclaw, openclaw_id.strip())
    if agent_entry is None and isinstance(workspace, str) and workspace.strip():
        agent_entry = resolve_existing_agent_entry(config_path, openclaw, agent_id, workspace.strip())
    if agent_entry is None:
        agent_entry = find_agent_entry(openclaw, agent_id)
    if agent_entry is None:
        raise ValueError(f"openclaw.json 中不存在 Agent: {agent_id}")

    timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
    backup_dir = backup_root / agent_id / timestamp
    backup_dir.mkdir(parents=True, exist_ok=True)

    workspace_backed_up = False
    workspace_path = agent_entry.get("workspace")
    copied_md_files: list[str] = []
    if isinstance(workspace_path, str) and Path(workspace_path).exists():
        copied_md_files = backup_md_files(Path(workspace_path), backup_dir)
        workspace_backed_up = bool(copied_md_files)

    return {
        "agent_id": agent_id,
        "openclaw_id": agent_entry.get("id"),
        "status": status,
        "backup_dir": str(backup_dir),
        "workspace_backed_up": workspace_backed_up,
        "workspace": workspace_path,
        "copied_md_files": copied_md_files,
        "message": "Agent 配置备份完成，已备份 workspace 下的 .md 文件。",
    }


def main() -> int:
    parser = argparse.ArgumentParser(description="备份已安装 Agent")
    parser.add_argument("--agent-id", required=True, help="Agent ID")
    parser.add_argument("--openclaw-id", help="当前 openclaw 条目 id（check_installed / openclaw 解析结果）")
    parser.add_argument("--workspace", help="当前 workspace（流程确认结果）")
    parser.add_argument(
        "--status",
        required=True,
        help="check_installed 状态，仅允许 UPDATABLE 或 SAME_VERSION_REINSTALL",
    )
    parser.add_argument(
        "--config",
        default=str(default_openclaw_config_path()),
        help="openclaw.json 路径",
    )
    parser.add_argument(
        "--backup-root",
        default=os.path.expanduser("~/.openclaw/backups"),
        help="备份根目录",
    )
    args = parser.parse_args()

    result = backup_agent(
        args.agent_id,
        args.status,
        Path(args.config).expanduser().resolve(),
        Path(args.backup_root).expanduser().resolve(),
        openclaw_id=args.openclaw_id,
        workspace=args.workspace,
    )
    json.dump(result, sys.stdout, indent=2, ensure_ascii=False)
    sys.stdout.write("\n")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
