"""Keep only public SDK archive bytes in the job's optional, digest-scoped download cache."""
from contextlib import contextmanager
import os
from pathlib import Path
import tempfile

import flutter_download


def cached_directory() -> Path:
    root = Path(os.environ["GOWALK_FLUTTER_ARCHIVE_CACHE"])
    temporary = Path(os.environ["RUNNER_TEMP"]).resolve(strict=True)
    if root.is_symlink() or root.parent.resolve(strict=True) != temporary:
        raise ValueError("flutter_archive_cache_scope_invalid")
    root.mkdir(mode=0o700, exist_ok=True)
    directory = root / flutter_download.archive_digest()
    if directory.is_symlink():
        raise ValueError("flutter_archive_cache_scope_invalid")
    directory.mkdir(mode=0o700, exist_ok=True)
    destination = directory / "download"
    if destination.is_symlink() or (destination.exists() and not destination.is_file()):
        raise ValueError("flutter_archive_cache_scope_invalid")
    if destination.exists() and destination.stat().st_size > flutter_download.MAX_ARCHIVE_BYTES:
        raise ValueError("flutter_archive_size_exceeded")
    return directory


@contextmanager
def workspace(kind: str):
    if kind != "archive" or not os.environ.get("GOWALK_FLUTTER_ARCHIVE_CACHE"):
        with tempfile.TemporaryDirectory(prefix="flutter-manifest-", dir=os.environ["RUNNER_TEMP"]) as scratch:
            yield Path(scratch)
        return
    directory = cached_directory()
    try:
        yield directory
    except ValueError as error:
        if str(error) == "flutter_archive_checksum_mismatch":
            (directory / "download").unlink(missing_ok=True)
        raise


def reuse_complete(destination: Path, kind: str) -> bool:
    if kind != "archive" or not destination.stat().st_size or not flutter_download.archive_matches(destination):
        return False
    flutter_download.publish(destination, kind)
    return True
