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

# Usage:
#   sudo ./v3_repo-mirror.sh <wave-name> [previous-wave-name]
#
# Examples:
#   sudo ./v3_repo-mirror.sh wave-001-2026-02-24
#   sudo ./v3_repo-mirror.sh wave-002-2026-03-15 wave-001-2026-02-24
#   sudo ./v3_repo-mirror.sh wave-001-2026-02-24   # rerun existing wave
#
# Notes:
# - If previous wave is provided, this script seeds the new wave with hard links
#   using cp -al (same filesystem required).
# - If the target wave already exists, the script reuses it.
# - If the target wave already exists, you may NOT provide a previous wave name.
# - Archive, security, and upgrader phases run independently so one failure
#   does not block the others.
# - The script exits non-zero at the end if any phase failed or required files
#   are missing.

NEW_WAVE="${1:-}"
PREV_WAVE="${2:-}"

if [[ -z "$NEW_WAVE" ]]; then
  echo "Usage: $0 <wave-name> [previous-wave-name]"
  exit 1
fi

# ---- CONFIG ----
MIRROR_ROOT="/srv/ubuntu-mirror"
WAVES_ROOT="$MIRROR_ROOT/waves"

# This must be the hostname clients will use to reach this mirror.
MIRROR_FQDN="216.71.188.133"

NEW_WAVE_DIR="$WAVES_ROOT/$NEW_WAVE"
ARCHIVE_DIR="$NEW_WAVE_DIR/archive"
SECURITY_DIR="$NEW_WAVE_DIR/security"
UPGRADER_DIR="$NEW_WAVE_DIR/upgrader"

COMPONENTS="main,restricted,universe"
ARCH="amd64"

ARCHIVE_HOST="archive.ubuntu.com"
ARCHIVE_ROOT="ubuntu"
ARCHIVE_DISTS="jammy,jammy-updates,noble,noble-updates"

SECURITY_HOST="security.ubuntu.com"
SECURITY_ROOT="ubuntu"
SECURITY_DISTS="jammy-security,noble-security"

META_RELEASE_LTS_URL="https://changelogs.ubuntu.com/meta-release-lts"
UPGRADE_BASE_URL="https://archive.ubuntu.com/ubuntu/dists/noble-updates/main/dist-upgrader-all/current"
# ----------------

echo "== Ubuntu wave mirror build =="
echo "New wave:      $NEW_WAVE"
echo "Wave dir:      $NEW_WAVE_DIR"
echo "Archive dir:   $ARCHIVE_DIR"
echo "Security dir:  $SECURITY_DIR"
echo "Upgrader dir:  $UPGRADER_DIR"
echo "Mirror FQDN:   $MIRROR_FQDN"
if [[ -n "$PREV_WAVE" ]]; then
  echo "Seed from:     $PREV_WAVE"
fi
echo "Components:    $COMPONENTS"
echo "Arch:          $ARCH"
echo

command -v debmirror >/dev/null || { echo "ERROR: debmirror not found"; exit 1; }
command -v cp >/dev/null || { echo "ERROR: cp not found"; exit 1; }
command -v curl >/dev/null || { echo "ERROR: curl not found"; exit 1; }
command -v sed >/dev/null || { echo "ERROR: sed not found"; exit 1; }

mkdir -p "$WAVES_ROOT"

# Build or reuse target wave
if [[ -d "$NEW_WAVE_DIR" ]]; then
  echo "Wave already exists, reusing it."

  if [[ -n "$PREV_WAVE" ]]; then
    echo "ERROR: target wave already exists, so it cannot be seeded again."
    echo "Re-run without a previous-wave argument:"
    echo "  $0 $NEW_WAVE"
    exit 1
  fi

  [[ -d "$ARCHIVE_DIR" ]]  || { echo "ERROR: missing archive dir: $ARCHIVE_DIR"; exit 1; }
  [[ -d "$SECURITY_DIR" ]] || { echo "ERROR: missing security dir: $SECURITY_DIR"; exit 1; }
  mkdir -p "$UPGRADER_DIR"

else
  if [[ -n "$PREV_WAVE" ]]; then
    PREV_WAVE_DIR="$WAVES_ROOT/$PREV_WAVE"
    PREV_ARCHIVE_DIR="$PREV_WAVE_DIR/archive"
    PREV_SECURITY_DIR="$PREV_WAVE_DIR/security"

    [[ -d "$PREV_ARCHIVE_DIR" ]]  || { echo "ERROR: missing previous archive dir: $PREV_ARCHIVE_DIR"; exit 1; }
    [[ -d "$PREV_SECURITY_DIR" ]] || { echo "ERROR: missing previous security dir: $PREV_SECURITY_DIR"; exit 1; }

    echo "Seeding new wave with hard links (cp -al)..."
    mkdir -p "$NEW_WAVE_DIR"
    cp -al "$PREV_ARCHIVE_DIR" "$ARCHIVE_DIR"
    cp -al "$PREV_SECURITY_DIR" "$SECURITY_DIR"
    mkdir -p "$UPGRADER_DIR"
  else
    echo "Creating empty wave directories..."
    mkdir -p "$ARCHIVE_DIR" "$SECURITY_DIR" "$UPGRADER_DIR"
  fi
fi

echo

archive_rc=0
security_rc=0
upgrader_rc=0

echo "=== ARCHIVE PASS START ==="
debmirror "$ARCHIVE_DIR" \
  --host="$ARCHIVE_HOST" \
  --root="$ARCHIVE_ROOT" \
  --method=http \
  --dist="$ARCHIVE_DISTS" \
  --section="$COMPONENTS" \
  --arch="$ARCH" \
  --nosource \
  --progress \
  --verbose || archive_rc=$?
echo "=== ARCHIVE PASS END (rc=$archive_rc) ==="
echo

echo "=== SECURITY PASS START ==="
debmirror "$SECURITY_DIR" \
  --host="$SECURITY_HOST" \
  --root="$SECURITY_ROOT" \
  --method=http \
  --dist="$SECURITY_DISTS" \
  --section="$COMPONENTS" \
  --arch="$ARCH" \
  --nosource \
  --progress \
  --verbose || security_rc=$?
echo "=== SECURITY PASS END (rc=$security_rc) ==="
echo

echo "=== UPGRADER PASS START ==="
(
  set -e

  cd "$UPGRADER_DIR"

  echo "Downloading meta-release-lts..."
  curl -fsSLo meta-release-lts "$META_RELEASE_LTS_URL"

  echo "Downloading Noble upgrader assets..."
  curl -fsSLo ReleaseAnnouncement      "$UPGRADE_BASE_URL/ReleaseAnnouncement"
  curl -fsSLo ReleaseAnnouncement.html "$UPGRADE_BASE_URL/ReleaseAnnouncement.html"
  curl -fsSLo noble.tar.gz             "$UPGRADE_BASE_URL/noble.tar.gz"
  curl -fsSLo noble.tar.gz.gpg         "$UPGRADE_BASE_URL/noble.tar.gz.gpg"

  echo "Rewriting meta-release-lts to point to this wave..."
  sed -i \
    -e "s#http://archive.ubuntu.com/ubuntu/dists/noble-updates/Release#http://$MIRROR_FQDN/waves/$NEW_WAVE/archive/dists/noble-updates/Release#g" \
    -e "s#https://archive.ubuntu.com/ubuntu/dists/noble-updates/main/dist-upgrader-all/current/ReleaseAnnouncement#http://$MIRROR_FQDN/waves/$NEW_WAVE/upgrader/ReleaseAnnouncement#g" \
    -e "s#http://archive.ubuntu.com/ubuntu/dists/noble-updates/main/dist-upgrader-all/current/ReleaseAnnouncement#http://$MIRROR_FQDN/waves/$NEW_WAVE/upgrader/ReleaseAnnouncement#g" \
    -e "s#https://archive.ubuntu.com/ubuntu/dists/noble-updates/main/dist-upgrader-all/current/ReleaseAnnouncement.html#http://$MIRROR_FQDN/waves/$NEW_WAVE/upgrader/ReleaseAnnouncement.html#g" \
    -e "s#http://archive.ubuntu.com/ubuntu/dists/noble-updates/main/dist-upgrader-all/current/ReleaseAnnouncement.html#http://$MIRROR_FQDN/waves/$NEW_WAVE/upgrader/ReleaseAnnouncement.html#g" \
    -e "s#https://archive.ubuntu.com/ubuntu/dists/noble-updates/main/dist-upgrader-all/current/noble.tar.gz#http://$MIRROR_FQDN/waves/$NEW_WAVE/upgrader/noble.tar.gz#g" \
    -e "s#http://archive.ubuntu.com/ubuntu/dists/noble-updates/main/dist-upgrader-all/current/noble.tar.gz#http://$MIRROR_FQDN/waves/$NEW_WAVE/upgrader/noble.tar.gz#g" \
    -e "s#https://archive.ubuntu.com/ubuntu/dists/noble-updates/main/dist-upgrader-all/current/noble.tar.gz.gpg#http://$MIRROR_FQDN/waves/$NEW_WAVE/upgrader/noble.tar.gz.gpg#g" \
    -e "s#http://archive.ubuntu.com/ubuntu/dists/noble-updates/main/dist-upgrader-all/current/noble.tar.gz.gpg#http://$MIRROR_FQDN/waves/$NEW_WAVE/upgrader/noble.tar.gz.gpg#g" \
    meta-release-lts
) || upgrader_rc=$?
echo "=== UPGRADER PASS END (rc=$upgrader_rc) ==="
echo

echo "Validating expected files..."

missing=0

# Archive checks
for f in \
  "$ARCHIVE_DIR/dists/jammy/Release" \
  "$ARCHIVE_DIR/dists/jammy-updates/Release" \
  "$ARCHIVE_DIR/dists/noble/Release" \
  "$ARCHIVE_DIR/dists/noble-updates/Release"
do
  if [[ -f "$f" ]]; then
    echo "OK: $f"
  else
    echo "MISSING: $f"
    missing=1
  fi
done

# Security checks
for f in \
  "$SECURITY_DIR/dists/jammy-security/Release" \
  "$SECURITY_DIR/dists/noble-security/Release"
do
  if [[ -f "$f" ]]; then
    echo "OK: $f"
  else
    echo "MISSING: $f"
    missing=1
  fi
done

# Upgrader checks
for f in \
  "$UPGRADER_DIR/meta-release-lts" \
  "$UPGRADER_DIR/ReleaseAnnouncement" \
  "$UPGRADER_DIR/ReleaseAnnouncement.html" \
  "$UPGRADER_DIR/noble.tar.gz" \
  "$UPGRADER_DIR/noble.tar.gz.gpg"
do
  if [[ -f "$f" ]]; then
    echo "OK: $f"
  else
    echo "MISSING: $f"
    missing=1
  fi
done

echo
echo "Summary:"
echo "  archive rc : $archive_rc"
echo "  security rc: $security_rc"
echo "  upgrader rc: $upgrader_rc"
echo "  missing flag: $missing"
echo

if [[ "$archive_rc" -ne 0 || "$security_rc" -ne 0 || "$upgrader_rc" -ne 0 || "$missing" -ne 0 ]]; then
  echo "RESULT: FAILURE"
  exit 1
fi

echo "RESULT: SUCCESS"
exit 0
 