#!/usr/bin/env bash
set -euo pipefail

repo="${1:-pypi}"
tag="${2:-${RELEASE_TAG:-}}"
if [ -z "$tag" ]; then
  echo "usage: scripts/release/build <pypi|testpypi> vX.Y.Z" >&2
  exit 1
fi
version="${tag#v}"
if [ "$version" = "$tag" ]; then
  echo "expected v-prefixed tag, got: $tag" >&2
  exit 1
fi

case "$repo" in
  pypi|testpypi) ;;
  *)
    echo "unknown repository: $repo" >&2
    exit 1
    ;;
esac

if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
  echo "scripts/release/build must be run from a git working tree" >&2
  exit 1
fi

current_tag="$(git describe --tags --exact-match HEAD 2>/dev/null || true)"
if [ "$current_tag" != "$tag" ]; then
  echo "HEAD is not checked out at tag $tag" >&2
  exit 1
fi

if ! git diff --quiet --no-ext-diff || ! git diff --cached --quiet --no-ext-diff; then
  echo "working tree is dirty; commit or stash changes before building a release" >&2
  exit 1
fi

if [ -n "$(git ls-files --others --exclude-standard)" ]; then
  echo "working tree has untracked files; clean it before building a release" >&2
  exit 1
fi

PYTHON_BIN="${PYTHON_BIN:-python3}"
export PYTHON_BIN
"$PYTHON_BIN" -m pip install --upgrade pip
"$PYTHON_BIN" -m pip install build twine

staging="$(mktemp -d)"
trap 'rm -rf "$staging"' EXIT
"$PYTHON_BIN" - <<'INNERPY' "$staging"
from pathlib import Path
import shutil, sys
src = Path('.').resolve()
dst = Path(sys.argv[1])
for child in src.iterdir():
    if child.name in {'.git', 'artifacts', 'build', 'dist', '.venv', '__pycache__', '.pytest_cache'}:
        continue
    target = dst / child.name
    if child.is_dir():
        shutil.copytree(child, target)
    else:
        shutil.copy2(child, target)
INNERPY

expected_project_name="confumo"
if [ "$repo" = "testpypi" ]; then
  "$PYTHON_BIN" scripts/release/rewrite_pyproject_name.py \
    "$staging/pyproject.toml" confumo TestConfumo
  expected_project_name="TestConfumo"
fi

output_dir="$(git rev-parse --show-toplevel)/artifacts/release/$repo"
rm -rf "$output_dir"
mkdir -p "$output_dir"
(
  cd "$staging"
  rm -rf dist
  SETUPTOOLS_SCM_PRETEND_VERSION="$version" "$PYTHON_BIN" -m build
  "$PYTHON_BIN" -m twine check dist/*
  cp -f dist/*.whl dist/*.tar.gz "$output_dir/"
)

shopt -s nullglob
artifacts=("$output_dir"/*.whl "$output_dir"/*.tar.gz)
shopt -u nullglob
if [ ${#artifacts[@]} -eq 0 ]; then
  echo "no release artifacts were staged under $output_dir" >&2
  exit 1
fi

"$PYTHON_BIN" - <<'INNERPY' "$expected_project_name" "$version" "${artifacts[@]}"
from pathlib import Path
import re
import sys

expected_name = sys.argv[1]
expected_version = sys.argv[2]
files = [Path(arg) for arg in sys.argv[3:]]

def normalize(name: str) -> str:
    return re.sub(r"[-_.]+", "-", name).lower()

expected = normalize(expected_name)
bad: list[str] = []
for path in files:
    base = path.name
    if base.endswith(".tar.gz"):
        suffix = f"-{expected_version}.tar.gz"
        dist_name = base[: -len(suffix)] if base.endswith(suffix) else ""
    elif base.endswith(".whl"):
        marker = f"-{expected_version}-"
        dist_name = base.split(marker, 1)[0] if marker in base else ""
    else:
        dist_name = ""

    if not dist_name or normalize(dist_name) != expected:
        bad.append(base)

if bad:
    raise SystemExit(
        "release artifact distribution name mismatch "
        f"for expected project {expected_name!r}: " + ", ".join(bad)
    )
INNERPY

echo "Built artifacts under $output_dir/"
