from __future__ import annotations

import json
import threading
from pathlib import Path
from typing import Dict, List

from config import HOST_SANDBOX_MACOS_WRITABLE_PATHS

_LOCK = threading.Lock()
_POLICY_PATH = Path(__file__).resolve().parents[1] / "config" / "host_sandbox_policy.json"


def _ensure_file() -> None:
    if _POLICY_PATH.exists():
        return
    _POLICY_PATH.parent.mkdir(parents=True, exist_ok=True)
    _POLICY_PATH.write_text(
        json.dumps({"macos_writable_paths": [], "macos_readable_extra_paths": []}, ensure_ascii=False, indent=2),
        encoding="utf-8",
    )


def load_policy() -> Dict:
    with _LOCK:
        _ensure_file()
        try:
            data = json.loads(_POLICY_PATH.read_text(encoding="utf-8"))
        except Exception:
            data = {"macos_writable_paths": [], "macos_readable_extra_paths": []}
        if not isinstance(data, dict):
            data = {"macos_writable_paths": [], "macos_readable_extra_paths": []}
        writable_items = data.get("macos_writable_paths")
        if not isinstance(writable_items, list):
            writable_items = []
        readable_items = data.get("macos_readable_extra_paths")
        if not isinstance(readable_items, list):
            readable_items = []
        data["macos_writable_paths"] = [str(x).strip() for x in writable_items if str(x).strip()]
        data["macos_readable_extra_paths"] = [str(x).strip() for x in readable_items if str(x).strip()]
        return data


def save_policy(policy: Dict) -> Dict:
    payload = dict(policy or {})
    writable_items = payload.get("macos_writable_paths")
    if not isinstance(writable_items, list):
        writable_items = []
    readable_items = payload.get("macos_readable_extra_paths")
    if not isinstance(readable_items, list):
        readable_items = []
    payload["macos_writable_paths"] = [str(x).strip() for x in writable_items if str(x).strip()]
    payload["macos_readable_extra_paths"] = [str(x).strip() for x in readable_items if str(x).strip()]
    with _LOCK:
        _ensure_file()
        _POLICY_PATH.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
    return payload


def get_macos_writable_paths() -> List[str]:
    file_items = load_policy().get("macos_writable_paths", [])
    merged: List[str] = []
    for raw in list(HOST_SANDBOX_MACOS_WRITABLE_PATHS or []) + list(file_items or []):
        val = str(raw).strip()
        if val and val not in merged:
            merged.append(val)
    return merged


def get_macos_readable_paths() -> List[str]:
    data = load_policy()
    readable_extra = data.get("macos_readable_extra_paths", [])
    merged: List[str] = []
    for raw in list(get_macos_writable_paths()) + list(readable_extra or []):
        val = str(raw).strip()
        if val and val not in merged:
            merged.append(val)
    return merged
