#!/usr/bin/env bash
# tag-day.sh — Lumotia tag-day orchestrator
#
# One command runs the entire morning-of release dance:
#   1. Run scripts/pre-tag-verify.sh (all 7 gates must be green)
#   2. Read the release version from src-tauri/Cargo.toml (or argv)
#   3. Check CHANGELOG.md for the 2026-MM-DD date placeholder — offer to fill
#      it with today's date, prompt for a custom date, or abort
#   4. Print git status + proposed tag command; prompt y/n
#   5. git tag -a vX.Y.Z -m "Release vX.Y.Z" + git push origin vX.Y.Z
#   6. Watch CI via `gh run watch` if gh CLI is present + authenticated
#   7. Print smoke-test next steps + link to tester-onboarding-kit.md
#
# Usage:
#   ./scripts/tag-day.sh [vX.Y.Z]
#
# If the version argument is omitted the script reads it from
# [workspace.package].version in Cargo.toml.
#
# Exit codes:
#   0  tag created and pushed (or all steps completed cleanly)
#   1  user aborted or a gate failed

set -euo pipefail

# ── helpers ──────────────────────────────────────────────────────────────────

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BOLD='\033[1m'
RESET='\033[0m'

REPO_ROOT="$(git -C "$(dirname "$0")" rev-parse --show-toplevel)"
cd "$REPO_ROOT"

info()  { printf "${BOLD}%s${RESET}\n" "$*"; }
ok()    { printf "${GREEN}  ✓${RESET}  %s\n" "$*"; }
warn()  { printf "${YELLOW}  ⚠${RESET}  %s\n" "$*"; }
abort() { printf "\n${RED}${BOLD}✗ ABORTED: %s${RESET}\n\n" "$*" >&2; exit 1; }

confirm() {
  # Usage: confirm "prompt text"  → returns 0 if user enters y/Y, exits otherwise
  local prompt="$1"
  read -r -p "$prompt [y/N] " ans
  case "$ans" in
    y|Y) return 0 ;;
    *) abort "User chose not to proceed." ;;
  esac
}

printf "\n${BOLD}╔══════════════════════════════════════════════╗${RESET}\n"
printf "${BOLD}║   Lumotia tag-day orchestrator                ║${RESET}\n"
printf "${BOLD}╚══════════════════════════════════════════════╝${RESET}\n\n"

# ── Step 1: pre-tag verification ─────────────────────────────────────────────

info "Step 1/7 — Running scripts/pre-tag-verify.sh (all 7 gates must pass)..."

VERIFY="$REPO_ROOT/scripts/pre-tag-verify.sh"
if [[ ! -f "$VERIFY" ]]; then
  abort "scripts/pre-tag-verify.sh not found. Restore it before running tag-day."
fi
if [[ ! -x "$VERIFY" ]]; then
  abort "scripts/pre-tag-verify.sh is not executable. Run: chmod +x scripts/pre-tag-verify.sh"
fi

# pre-tag-verify.sh already exits non-zero on any failure; we let it print its
# own output so the user sees exactly what failed.
if ! bash "$VERIFY"; then
  abort "pre-tag-verify.sh reported failures — see output above. Fix and re-run tag-day.sh."
fi

ok "All 7 pre-tag gates passed."

# ── Step 2: resolve version ───────────────────────────────────────────────────

info "Step 2/7 — Resolving release version..."

if [[ $# -ge 1 && -n "$1" ]]; then
  VERSION="${1#v}"  # strip leading 'v' if supplied
  TAG="v${VERSION}"
  ok "Version from argv: ${TAG}"
else
  # Extract from [workspace.package].version in root Cargo.toml
  VERSION=$(grep -A10 '^\[workspace\.package\]' Cargo.toml \
    | grep '^version' \
    | head -1 \
    | grep -oP '"\K[^"]+' 2>/dev/null || true)
  if [[ -z "$VERSION" ]]; then
    abort "Could not parse version from Cargo.toml [workspace.package]. Pass it as an argument: ./scripts/tag-day.sh v0.1.0"
  fi
  TAG="v${VERSION}"
  ok "Version from Cargo.toml: ${TAG}"
fi

# ── Step 3: CHANGELOG date check ─────────────────────────────────────────────

info "Step 3/7 — Checking CHANGELOG.md for date placeholder..."

if [[ ! -f CHANGELOG.md ]]; then
  abort "CHANGELOG.md not found at repo root."
fi

TODAY="$(date -u +%Y-%m-%d)"

if grep -qE '[0-9]{4}-MM-DD' CHANGELOG.md; then
  printf "\n"
  warn "CHANGELOG.md still has the date placeholder. Today is ${TODAY}."
  printf "Replace placeholder with today's date? [y/N/abort] "
  read -r changelog_ans
  case "$changelog_ans" in
    y|Y)
      sed -i "s/[0-9]\{4\}-MM-DD/${TODAY}/g" CHANGELOG.md
      ok "Replaced date placeholder in CHANGELOG.md with ${TODAY}."
      # Verify replacement
      if grep -qE '[0-9]{4}-MM-DD' CHANGELOG.md; then
        abort "sed replacement did not remove all placeholders. Check CHANGELOG.md manually."
      fi
      ;;
    n|N)
      printf "  Enter the release date to use (YYYY-MM-DD): "
      read -r custom_date
      if [[ ! "$custom_date" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
        abort "Date '${custom_date}' is not in YYYY-MM-DD format."
      fi
      sed -i "s/[0-9]\{4\}-MM-DD/${custom_date}/g" CHANGELOG.md
      ok "Replaced date placeholder in CHANGELOG.md with ${custom_date}."
      if grep -qE '[0-9]{4}-MM-DD' CHANGELOG.md; then
        abort "sed replacement did not remove all placeholders. Check CHANGELOG.md manually."
      fi
      ;;
    abort|ABORT|a)
      abort "User chose to abort at CHANGELOG date step."
      ;;
    *)
      abort "Unrecognised response '${changelog_ans}'. Aborting. Valid responses: y / n / abort"
      ;;
  esac
else
  ok "CHANGELOG.md has no date placeholder — ready."
fi

# ── Step 4: git status + confirm tag command ──────────────────────────────────

info "Step 4/7 — Reviewing git status and confirming tag..."

printf "\n── git status ───────────────────────────────────────────────────────────\n"
git status --short
printf "─────────────────────────────────────────────────────────────────────────\n\n"

printf "Proposed commands:\n"
printf "  ${BOLD}git tag -a %s -m \"Release %s\"${RESET}\n" "$TAG" "$TAG"
printf "  ${BOLD}git push origin %s${RESET}\n\n" "$TAG"

# Check if the tag already exists locally
if git tag --list "$TAG" | grep -q "$TAG"; then
  warn "Tag ${TAG} already exists locally."
  confirm "Delete the existing local tag and re-create it?"
  git tag -d "$TAG"
fi

confirm "Confirm: create tag ${TAG} and push to origin?"

# ── Step 5: tag + push ────────────────────────────────────────────────────────

info "Step 5/7 — Creating tag and pushing..."

git tag -a "$TAG" -m "Release ${TAG}"
ok "Tag ${TAG} created locally."

git push origin "$TAG"
ok "Tag ${TAG} pushed to origin."

# ── Step 6: CI watch (optional) ──────────────────────────────────────────────

info "Step 6/7 — CI watch..."

GH_OK=false
if command -v gh &>/dev/null; then
  if gh auth status &>/dev/null; then
    GH_OK=true
  else
    warn "gh CLI found but not authenticated (gh auth status failed). Skipping CI watch."
  fi
else
  warn "gh CLI not installed. Skipping CI watch."
fi

if $GH_OK; then
  printf "\n  Opening CI run for tag ${TAG}...\n"
  # Wait a moment for the push to register with GitHub
  sleep 3
  # gh run watch will block until the run completes; Ctrl-C to detach.
  if ! gh run watch --exit-status 2>&1; then
    warn "CI run watch exited non-zero or was interrupted. Check manually:"
    printf "  https://github.com/jakeadriansames/lumotia/actions\n\n"
  else
    ok "CI completed successfully."
  fi
else
  printf "\n  Open this URL to watch CI:\n"
  printf "  ${BOLD}https://github.com/jakeadriansames/lumotia/actions${RESET}\n\n"
fi

# ── Step 7: next steps ────────────────────────────────────────────────────────

info "Step 7/7 — Smoke-test next steps"

printf "\n"
printf "  Once CI has produced artefacts for all platforms:\n\n"
printf "    1. Download the Linux AppImage from the CI release artefacts.\n"
printf "    2. Run the smoke harness against it:\n"
printf "       ${BOLD}./scripts/smoke-linux.sh /path/to/lumotia-%s-linux-x86_64.AppImage${RESET}\n" "$VERSION"
printf "    3. Complete the manual cells (Capture, Cleanup, Export, History search).\n"
printf "    4. Repeat on macOS / Windows if testers are available.\n"
printf "    5. Fill in the smoke-test matrix in docs/release/v0.1-checklist.md.\n\n"
printf "  Tester onboarding kit:\n"
printf "    ${BOLD}docs/release/tester-onboarding-kit.md${RESET}\n\n"

printf "${GREEN}${BOLD}✓ Tag day complete. Tag %s is live on origin.${RESET}\n\n" "$TAG"
