"""Platform-managed file sync — version tracking and content generation.

When platform files (AI rules, platform manifest, access docs) change, bump
PLATFORM_FILES_VERSION. The sync worker detects projects/templates whose
``platform_files_version`` column is NULL or behind and pushes only the
managed files — user code is never touched.

To ship a new version of the platform files:
  1. Update the boilerplate files under boilerplates/<framework>/
  2. Bump PLATFORM_FILES_VERSION below
  3. Deploy — the next admin sync (or scheduled run) propagates to all repos
"""
from __future__ import annotations

from typing import Union

PLATFORM_FILES_VERSION = "1.1.0"

# Only these paths are ever written by the sync task.
# User code outside these paths is always preserved.
MANAGED_FILE_PATHS: dict[str, list[str]] = {
    "nuxt_app": [
        ".cursor/instructions.md",
        "p2hs/cloud-access.md",
        "p2hs/backend-contract.md",
    ],
    "react_app": [
        ".cursor/instructions.md",
        "p2hs/cloud-access.md",
        "p2hs/backend-contract.md",
    ],
    "html": [
        "p2hs/cloud-access.md",
        "p2hs/backend-contract.md",
        ".cursor/instructions.md",
    ],
    "shopify_app": [
        ".cursorrules",
        ".cursor/instructions.md",
    ],
}


def get_managed_files(framework: str, settings=None) -> dict[str, Union[str, bytes]]:
    """Return current content of all managed files for a framework.

    Reads from the latest boilerplate snapshot (or boilerplates/ directory on
    disk), then filters to only the managed paths. Generated files (manifest,
    readme) are always produced fresh so they reflect the latest constants.
    Returns an empty dict when the framework is unknown or has no managed files.
    """
    from src.domain.templates.service import _collect_seed_files

    managed_paths = set(MANAGED_FILE_PATHS.get(framework, []))
    if not managed_paths:
        return {}
    all_files = _collect_seed_files(framework, settings)
    return {k: v for k, v in all_files.items() if k in managed_paths}


def write_managed_files(repo_path: str, framework: str, settings=None) -> list[str]:
    """Write current platform manifest/contract files into an existing checkout."""
    from pathlib import Path

    written: list[str] = []
    root = Path(repo_path)
    for rel, content in get_managed_files(framework, settings).items():
        path = root / rel
        path.parent.mkdir(parents=True, exist_ok=True)
        if isinstance(content, bytes):
            path.write_bytes(content)
        else:
            path.write_text(content, encoding="utf-8")
        written.append(rel.replace("\\", "/"))
    return written
