"""SO file description database loader.

This is used to enrich the "SO Architecture Matrix" with human-friendly hints
for known native libraries.
"""

from __future__ import annotations

from pathlib import Path
import re
import sys

try:
    import yaml  # type: ignore
except Exception:  # pragma: no cover
    yaml = None


def _parse_yaml_mapping_fallback(text: str) -> dict[str, str]:
    """Very small YAML mapping parser (key: value)."""
    out: dict[str, str] = {}
    for raw in text.splitlines():
        line = raw.strip()
        if not line or line.startswith("#") or ":" not in line:
            continue
        k, _, v = line.partition(":")
        key = k.strip().strip('"').strip("'")
        val = v.strip().strip('"').strip("'")
        if key:
            out[key] = val
    return out


def _default_so_db_file() -> Path:
    if getattr(sys, "frozen", False):
        return Path(sys.executable).parent / "so_database" / "so_files.yaml"
    pkg_dir = Path(__file__).parent
    candidate = pkg_dir / "so_database" / "so_files.yaml"
    if candidate.exists():
        return candidate
    repo_root = pkg_dir.parent.parent
    candidate = repo_root / "src" / "apk_analyzer" / "so_database" / "so_files.yaml"
    if candidate.exists():
        return candidate
    return pkg_dir / "so_database" / "so_files.yaml"


def load_so_file_descriptions(path: Path | None = None) -> dict[str, str]:
    db_file = path or _default_so_db_file()
    if not db_file.exists():
        return {}
    try:
        text = db_file.read_text(encoding="utf-8")
    except Exception:
        return {}

    try:
        if yaml:
            data = yaml.safe_load(text)
        else:
            data = _parse_yaml_mapping_fallback(text)
    except Exception:
        data = _parse_yaml_mapping_fallback(text)

    if isinstance(data, dict):
        return {str(k): str(v) for k, v in data.items() if k}
    return {}


_VERSIONED_SO_PATTERN = re.compile(r"^(lib.+?)(_v\d+(?:_\d+)*)\.so$")


def normalize_so_name(so_name: str) -> str:
    """
    Normalize SO filename for database lookup.

    Example:
    - libAMapSDK_MAP_v9_6_0.so -> libAMapSDK_MAP.so

    If no known pattern matches, the original name is returned.
    """
    m = _VERSIONED_SO_PATTERN.match(so_name)
    if m:
        return f"{m.group(1)}.so"
    return so_name

