"""Resolve the WordPress companion package from Core boilerplate snapshots."""
from __future__ import annotations

import hashlib
from dataclasses import dataclass
from pathlib import Path

from src.config import get_settings
from src.workers.boilerplate_store import find_latest_version, get_snapshot_dir, snapshot_path

COMPANION_PROJECT_TYPE = "wordpress_companion"
LIVE_COMPANION_VERSION = "live"


@dataclass(frozen=True)
class WordPressCompanionPackage:
    version: str
    path: Path
    sha256: str


def resolve_wordpress_companion_package(
    requested_version: str | None = None,
) -> WordPressCompanionPackage | None:
    """Return the requested/latest companion package.

    Preferred source matches the normal boilerplate system:
    ``boilerplates/snapshots/wordpress_companion@<version>.tar.gz``.

    For local/dev continuity, fall back to the checked-in live archive at
    ``boilerplates/wordpress_companion/p2hs-companion.tar.gz``.
    """
    version = (requested_version or "").strip()
    snapshot_dir = get_snapshot_dir(get_settings())

    if version and version != LIVE_COMPANION_VERSION:
        path = Path(snapshot_path(COMPANION_PROJECT_TYPE, version, snapshot_dir))
        if path.is_file():
            return _package(version, path)
        return None

    latest = find_latest_version(COMPANION_PROJECT_TYPE, snapshot_dir)
    if latest:
        path = Path(snapshot_path(COMPANION_PROJECT_TYPE, latest, snapshot_dir))
        if path.is_file():
            return _package(latest, path)

    live = _live_companion_archive()
    if live.is_file():
        return _package(LIVE_COMPANION_VERSION, live)
    return None


def _live_companion_archive() -> Path:
    return (
        Path(__file__).resolve().parents[3]
        / "boilerplates"
        / COMPANION_PROJECT_TYPE
        / "p2hs-companion.tar.gz"
    )


def _package(version: str, path: Path) -> WordPressCompanionPackage:
    return WordPressCompanionPackage(
        version=version,
        path=path,
        sha256=_sha256(path),
    )


def _sha256(path: Path) -> str:
    digest = hashlib.sha256()
    with path.open("rb") as handle:
        for chunk in iter(lambda: handle.read(1024 * 1024), b""):
            digest.update(chunk)
    return digest.hexdigest()
