"""vault-sdk 核心读取逻辑。"""

from __future__ import annotations

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


class VaultError(Exception):
    """slug 不存在 / VAULT_DATA_DIR 未配 / 文件 corrupted 等。"""


def _data_dir() -> Path:
    d = os.environ.get("VAULT_DATA_DIR")
    if d:
        return Path(d)
    # 默认按软链约定
    return Path.home() / ".vault" / "data"


def _read(path: Path) -> dict[str, Any]:
    if not path.exists():
        raise VaultError(f"not found: {path}")
    try:
        return json.loads(path.read_text())
    except json.JSONDecodeError as e:
        raise VaultError(f"invalid json: {path}: {e}") from e


# -------- Primary APIs --------


def cred(slug: str) -> dict[str, Any]:
    """取 credential by slug。

    Example:
        >>> c = cred("aliyun-power-app-ak")
        >>> c["kind"]
        'ak_sk'
        >>> c["credentials"]["access_key_id"]
        'LTAI...'
    """
    return _read(_data_dir() / "credentials" / f"{slug}.json")


def account(slug: str) -> dict[str, Any]:
    """取 account by slug（`<platform>/<name>`）。

    Example:
        >>> account("aliyun/main")
    """
    if "/" not in slug:
        raise VaultError(f"account slug 必须是 platform/name 形式，收到 {slug!r}")
    platform, name = slug.split("/", 1)
    return _read(_data_dir() / "accounts" / platform / f"{name}.json")


def resource(platform: str, type_: str, id_: str) -> dict[str, Any]:
    """取 resource。

    Example:
        >>> r = resource("aliyun", "sms-sign", "杭州阿空智能科技")
        >>> r["credential_ref"]
        'aliyun-power-app-ak'
    """
    return _read(_data_dir() / "resources" / platform / type_ / f"{id_}.json")


def project(slug: str) -> dict[str, Any]:
    """取 project。

    Example:
        >>> p = project("xiangqin")
        >>> p["uses"]["credentials"]
        ['aliyun-main', 'aliyun-power-app-ak', ...]
    """
    return _read(_data_dir() / "projects" / f"{slug}.json")


# -------- Iteration helpers --------


def list_credentials() -> list[dict[str, Any]]:
    d = _data_dir() / "credentials"
    if not d.exists():
        return []
    return [_read(f) for f in sorted(d.glob("*.json"))]


def list_resources(
    platform: str | None = None, type_: str | None = None
) -> list[dict[str, Any]]:
    base = _data_dir() / "resources"
    if not base.exists():
        return []
    out: list[dict[str, Any]] = []
    platforms = [platform] if platform else sorted(p.name for p in base.iterdir() if p.is_dir())
    for p in platforms:
        p_dir = base / p
        if not p_dir.exists():
            continue
        types = [type_] if type_ else sorted(t.name for t in p_dir.iterdir() if t.is_dir())
        for t in types:
            t_dir = p_dir / t
            if not t_dir.exists():
                continue
            for f in sorted(t_dir.glob("*.json")):
                out.append(_read(f))
    return out


def list_projects() -> list[dict[str, Any]]:
    d = _data_dir() / "projects"
    if not d.exists():
        return []
    return [_read(f) for f in sorted(d.glob("*.json"))]


# -------- Search helper --------


def find_credential(legacy_platform: str) -> dict[str, Any] | None:
    """v1 兼容：按旧 platform 名找对应 credential。

    例：`find_credential("aliyun.power-app")` → credential slug `aliyun-power-app-ak`

    规则：把点号转 `-`，加 `-ak` / `-main` 后缀试；或扫描所有 credentials 看 account_ref
    匹配。返回 None 表示没找到。
    """
    # 尝试直接映射
    candidates = [
        legacy_platform.replace(".", "-"),
        legacy_platform.replace(".", "-") + "-ak",
        legacy_platform.replace(".", "-") + "-main",
    ]
    for slug in candidates:
        try:
            return cred(slug)
        except VaultError:
            continue

    # 扫所有 credentials 看 account_ref 匹配
    target_account = legacy_platform.replace(".", "/")
    for c in list_credentials():
        if c.get("account_ref") == target_account:
            return c
    return None
