"""Describe optional native caches from committed locks and the selected toolchain."""
from __future__ import annotations

import hashlib
import os
from pathlib import Path
import platform
import subprocess


def command(*words: str) -> bytes:
    return subprocess.check_output(words, stderr=subprocess.DEVNULL, timeout=30)


def describe(root: Path) -> dict:
    tracked = command("git", "-C", str(root), "ls-files", "-z").decode().split("\0")
    names = sorted(name for name in tracked if Path(name).name in
                   {"Podfile", "Podfile.lock", "Gemfile", "Gemfile.lock"})
    locks = [name for name in names if name.endswith(".lock")]
    if not locks:
        return {"key": "", "paths": []}
    digest = hashlib.sha256()
    for value in (platform.system(), platform.machine(), command("ruby", "--version").decode(),
                  command("xcodebuild", "-version").decode()):
        digest.update(value.encode() + b"\0")
    for name in names:
        path = root / name
        if "\n" in name or "\r" in name or path.is_symlink():
            raise ValueError("native_cache_input_invalid")
        digest.update(name.encode() + b"\0" + path.read_bytes() + b"\0")
    paths = [str(Path(name).parent / "Pods") for name in locks if Path(name).name == "Podfile.lock"]
    if any(Path(name).name == "Gemfile.lock" for name in locks):
        paths.append(".factory/toolchain/gems")
    return {"key": "native-deps-v1-" + digest.hexdigest(), "paths": paths}


def main() -> None:
    value = describe(Path(os.environ.get("GITHUB_WORKSPACE", ".")))
    with open(os.environ["GITHUB_OUTPUT"], "a") as output:
        output.write("key=" + value["key"] + "\npaths<<NATIVE_CACHE_PATHS\n")
        output.write("\n".join(value["paths"]) + "\nNATIVE_CACHE_PATHS\n")


if __name__ == "__main__":
    main()
