# -*- coding: utf-8 -*-
"""Shared helpers for extended CLI commands."""

from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import Any, Dict, Iterable, List, Optional

from services.commands import USER_CONFIG_FILE, flatten_server_dirs


SENSITIVE_KEY_PARTS = ("pass", "password", "secret", "token", "cookie")


def add_json_flag(parser: argparse.ArgumentParser) -> None:
    parser.add_argument(
        "--json",
        action="store_true",
        default=argparse.SUPPRESS,
        help="以 JSON 输出，便于脚本和大模型读取",
    )


def is_json_output(args: argparse.Namespace) -> bool:
    return bool(getattr(args, "json", False))


def emit_json(data: Any) -> None:
    print(json.dumps(data, ensure_ascii=False, indent=2))


def is_sensitive_key(key: str) -> bool:
    lowered = key.lower()
    return any(part in lowered for part in SENSITIVE_KEY_PARTS)


def mask_config(config: Dict[str, Any], include_sensitive: bool = False) -> Dict[str, Any]:
    if include_sensitive:
        return dict(config)
    return {
        key: ("***" if is_sensitive_key(str(key)) else value)
        for key, value in config.items()
    }


def print_kv(data: Dict[str, Any]) -> None:
    if not data:
        print("(空)")
        return
    width = max(len(str(key)) for key in data)
    for key in sorted(data):
        print(f"{key:<{width}}  {data[key]}")


def all_servers(cli: Any) -> List[str]:
    return flatten_server_dirs(cli.run_dir)


def config_target_path(cli: Any, server: Optional[str] = None) -> Path:
    if server:
        return Path(cli.run_dir) / server / "config" / "kv.config"
    return Path(cli.config_path) / USER_CONFIG_FILE


def update_key_value_file(path: Path, updates: Optional[Dict[str, str]] = None,
                          unset_keys: Optional[Iterable[str]] = None) -> None:
    updates = updates or {}
    unset = set(unset_keys or [])
    path.parent.mkdir(parents=True, exist_ok=True)
    lines = path.read_text(encoding="utf-8").splitlines(True) if path.exists() else []
    written = set()
    output: List[str] = []

    for line in lines:
        stripped = line.strip()
        if not stripped or stripped.startswith("#") or stripped.startswith("%") or "=" not in line:
            output.append(line)
            continue
        key = line.split("=", 1)[0].strip()
        if key in unset:
            written.add(key)
            continue
        if key in updates:
            output.append(f"{key}={updates[key]}\n")
            written.add(key)
            continue
        output.append(line)

    for key, value in updates.items():
        if key not in written:
            output.append(f"{key}={value}\n")

    path.write_text("".join(output), encoding="utf-8")
