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

# gen_simple_inplace.sh
# Generate PEP 503 "simple" indexes in-place for existing directories:
#   <SIMPLE_DIR>/<pkg>/index.html
# Optionally generates:
#   <SIMPLE_DIR>/index.html

die() { echo "ERROR: $*" >&2; exit 1; }

SIMPLE_DIR=""
ONLY_PKG=""
NO_TOP=0
DO_VERIFY=0
VERIFY_ONLY=0

while [ $# -gt 0 ]; do
  case "$1" in
    --simple-dir) SIMPLE_DIR="${2:-}"; shift 2 ;;
    --pkg)        ONLY_PKG="${2:-}"; shift 2 ;;
    --no-top)     NO_TOP=1; shift ;;
    --verify)     DO_VERIFY=1; shift ;;
    --verify-only) VERIFY_ONLY=1; DO_VERIFY=1; shift ;;
    -h|--help)
      cat <<'EOF'
Usage:
  ./gen_simple_inplace.sh --simple-dir /var/www/.../simple
  ./gen_simple_inplace.sh --simple-dir /var/www/.../simple --pkg cffi --no-top
  ./gen_simple_inplace.sh --simple-dir /var/www/.../simple --verify
  ./gen_simple_inplace.sh --simple-dir /var/www/.../simple --verify-only
Options:
  --no-top   Don't rewrite /simple/index.html
  --verify   Verify that each <pkg>/index.html href exists and sha256 matches
  --verify-only  Verify only (do not regenerate any index.html)
EOF
      exit 0
      ;;
    *) die "Unknown arg: $1" ;;
  esac
done

[ -n "$SIMPLE_DIR" ] || die "--simple-dir is required"
[ -d "$SIMPLE_DIR" ] || die "Not a directory: $SIMPLE_DIR"

is_artifact() {
  case "$1" in
    *.whl|*.tar.gz|*.zip|*.tgz) return 0 ;;
    *) return 1 ;;
  esac
}

verify_pkg_index() {
  local pkgdir="$1"
  local pkgname="$2"
  local idx="$pkgdir/index.html"
  local errs=0

  if [ ! -f "$idx" ]; then
    echo "VERIFY FAIL [$pkgname]: missing index.html" >&2
    return 1
  fi

  # Extract href targets like: filename#sha256=....
  # We assume filenames don't contain quotes/spaces (true for wheels/sdists typically).
  while IFS= read -r href; do
    [ -n "$href" ] || continue
    local file="${href%%#sha256=*}"
    local want="${href##*#sha256=}"

    if [ ! -f "$pkgdir/$file" ]; then
      echo "VERIFY FAIL [$pkgname]: missing file: $file" >&2
      errs=$((errs+1))
      continue
    fi

    local got
    got="$(sha256sum "$pkgdir/$file" | awk '{print $1}')"
    if [ "$got" != "$want" ]; then
      echo "VERIFY FAIL [$pkgname]: sha256 mismatch for $file" >&2
      echo "  want: $want" >&2
      echo "  got : $got" >&2
      errs=$((errs+1))
    fi
  done < <(
    # Pull href="..."; keep only those containing #sha256=
    grep -oE 'href="[^"]+"' "$idx" \
      | sed -E 's/^href="(.*)"$/\1/' \
      | grep -E '#sha256=' || true
  )

  if [ "$errs" -gt 0 ]; then
    echo "VERIFY FAIL [$pkgname]: $errs error(s)" >&2
    return 1
  fi

  echo "VERIFY OK   [$pkgname]"
  return 0
}

write_pkg_index() {
  local pkgdir="$1"
  local pkgname="$2"
  local idx="$pkgdir/index.html"

  # Collect artifacts in that pkg dir
  mapfile -t files < <(find "$pkgdir" -maxdepth 1 -type f \( -name '*.whl' -o -name '*.tar.gz' -o -name '*.zip' -o -name '*.tgz' \) -printf '%f\n' | sort)

  # If no artifacts, skip (or you can still write an empty index if you want)
  [ "${#files[@]}" -gt 0 ] || return 0

  {
    echo "<!doctype html>"
    echo "<html><head><meta charset=\"utf-8\"><title>${pkgname}</title></head><body>"
    for bn in "${files[@]}"; do
      # hash the file in place
      sha="$(sha256sum "$pkgdir/$bn" | awk '{print $1}')"
      printf '<a href="%s#sha256=%s">%s</a><br/>\n' "$bn" "$sha" "$bn"
    done
    echo "</body></html>"
  } > "$idx"
}

# Determine package dirs
pkg_dirs=()
if [ -n "$ONLY_PKG" ]; then
  [ -d "$SIMPLE_DIR/$ONLY_PKG" ] || die "Package dir not found: $SIMPLE_DIR/$ONLY_PKG"
  pkg_dirs+=("$SIMPLE_DIR/$ONLY_PKG")
else
  # All subdirs except hidden ones
  while IFS= read -r d; do
    pkg_dirs+=("$d")
  done < <(find "$SIMPLE_DIR" -mindepth 1 -maxdepth 1 -type d ! -name '.*' | sort)
fi

if [ "$VERIFY_ONLY" -eq 0 ]; then
  # Generate per-package indexes
  for d in "${pkg_dirs[@]}"; do
    pkg="$(basename "$d")"
    write_pkg_index "$d" "$pkg"
  done

  # Top index (optional)
  if [ "$NO_TOP" -eq 0 ] && [ -z "$ONLY_PKG" ]; then
    top="$SIMPLE_DIR/index.html"
    {
      echo "<!doctype html>"
      echo "<html><head><meta charset=\"utf-8\"><title>Simple Index</title></head><body>"
      for d in "${pkg_dirs[@]}"; do
        pkg="$(basename "$d")"
        if find "$d" -maxdepth 1 -type f \( -name '*.whl' -o -name '*.tar.gz' -o -name '*.zip' -o -name '*.tgz' \) | grep -q .; then
          printf '<a href="./%s/">%s</a><br/>\n' "$pkg" "$pkg"
        fi
      done
      echo "</body></html>"
    } > "$top"
  fi
fi

if [ "$DO_VERIFY" -eq 1 ]; then
  vfail=0
  for d in "${pkg_dirs[@]}"; do
    pkg="$(basename "$d")"
    if ! verify_pkg_index "$d" "$pkg"; then
      vfail=1
    fi
  done
  if [ "$vfail" -ne 0 ]; then
    die "Verification failed"
  fi
fi

if [ "$VERIFY_ONLY" -eq 1 ]; then
  echo "OK: verified indexes under: $SIMPLE_DIR"
else
  echo "OK: indexes generated under: $SIMPLE_DIR"
fi
