# -*- coding: utf-8 -*-
"""Apps that bypass VPN and use home ISP (direct)."""
from __future__ import annotations

import json
import os
from datetime import datetime
from pathlib import Path
from typing import Any


def store_path() -> Path:
    p = Path(os.environ["USERPROFILE"]) / ".claude-proxy-control" / "merged" / "direct-apps.json"
    p.parent.mkdir(parents=True, exist_ok=True)
    return p


def _now() -> str:
    return datetime.now().isoformat(timespec="seconds")


def load_direct_apps() -> list[dict[str, Any]]:
    path = store_path()
    if not path.is_file():
        return []
    try:
        data = json.loads(path.read_text(encoding="utf-8"))
        if isinstance(data, list):
            return [x for x in data if isinstance(x, dict) and x.get("exe")]
    except Exception:
        return []
    return []


def save_direct_apps(apps: list[dict[str, Any]]) -> None:
    store_path().write_text(json.dumps(apps, ensure_ascii=False, indent=2), encoding="utf-8")


def list_exe_names() -> list[str]:
    names: list[str] = []
    for a in load_direct_apps():
        exe = str(a.get("exe") or "").strip()
        if exe and exe not in names:
            names.append(exe)
        # also bare name variants
        low = exe.lower()
        if exe and low != exe and low not in names:
            names.append(low)
    return names


def add_direct_app(exe: str, path: str = "") -> dict[str, Any]:
    exe = Path(exe).name if exe else ""
    if not exe:
        raise ValueError("empty exe")
    blocked = {"claude.exe", "cowork-svc.exe"}
    if exe.lower() in blocked:
        raise ValueError("Claude нельзя пускать через домашний IP — он всегда через Squid")
    apps = load_direct_apps()
    for a in apps:
        if str(a.get("exe", "")).lower() == exe.lower():
            a["path"] = path or a.get("path") or ""
            a["added_at"] = a.get("added_at") or _now()
            save_direct_apps(apps)
            return a
    row = {"exe": exe, "path": path or "", "added_at": _now()}
    apps.append(row)
    save_direct_apps(apps)
    return row


def remove_direct_app(exe: str) -> bool:
    exe_l = Path(exe).name.lower()
    apps = load_direct_apps()
    new = [a for a in apps if str(a.get("exe", "")).lower() != exe_l]
    if len(new) == len(apps):
        return False
    save_direct_apps(new)
    return True


def is_direct(exe: str) -> bool:
    exe_l = Path(exe).name.lower()
    return any(str(a.get("exe", "")).lower() == exe_l for a in load_direct_apps())
