#!/bin/bash
# Meta command for Omarchy repository management
# Usage: ./bin/repo <command> [options]

set -e

# Get the directory of this script
SCRIPT_DIR=$(realpath "${BASH_SOURCE[0]%/*}")
BUILD_ROOT=$(realpath "$SCRIPT_DIR/..")

# Source common functions
source "$BUILD_ROOT/helpers/message-helpers.sh"
source "$BUILD_ROOT/helpers/paths.sh"
source "$BUILD_ROOT/helpers/host-helpers.sh"

# --- remote control ----------------------------------------------------------
#
# With a repository host configured (OMARCHY_REPO_HOST or .repo-host), commands
# that operate on the published tree run ON the host over ssh — the exact same
# code, executed where the tree lives. This checkout is the remote control.
# Pass --local to force local execution. The host itself configures no
# .repo-host, so on it every command runs locally, ssh'd in or not.
#
# Local-machine workflows (list, push, deploy, setup) never forward: push and
# deploy exist precisely to move local builds TO the host.
FORWARDABLE=" release build sign promote update clean migrate advance bootstrap-rc remove sync timers "

LOCAL_OVERRIDE=false
STRIPPED_ARGS=()
for arg in "$@"; do
  if [[ "$arg" == "--local" ]]; then
    LOCAL_OVERRIDE=true
  else
    STRIPPED_ARGS+=("$arg")
  fi
done
set -- "${STRIPPED_ARGS[@]}"

maybe_forward_to_host() {
  local cmd="${1:-}"
  shift || true
  [[ "$LOCAL_OVERRIDE" == true ]] && return 0
  [[ "$FORWARDABLE" == *" $cmd "* ]] || return 0
  local host
  host=$(resolve_repo_host "") || return 0

  local quoted="" a
  for a in "$@"; do quoted+=" $(printf '%q' "$a")"; done

  # A tty makes the remote confirmation prompts (production sync, etc.) work;
  # without one locally, run non-interactively.
  local tty_flag=""
  [[ -t 0 && -t 1 ]] && tty_flag="-t"

  print_info "Repository host configured — running on $host (pass --local to run here)"
  exec ssh $tty_flag "$host" "source /root/.omarchy/build-credentials 2>/dev/null; cd /root/omarchy-pkgs && git pull --ff-only && exec bin/repo $cmd$quoted"
}

maybe_forward_to_host "$@"

# Extract mirror from arguments for log naming (before args are shifted)
LOG_MIRROR=""
for ((i=1; i<=$#; i++)); do
  if [[ "${!i}" == "--mirror" ]]; then
    next=$((i+1))
    LOG_MIRROR="${!next}"
    break
  fi
done

# Setup logging with timestamps
mkdir -p "$LOG_DIR"

# Rotate logs first - keep only the 10 most recent
if [[ -d "$LOG_DIR" ]]; then
  cd "$LOG_DIR"
  # List logs by modification time (newest first), skip first 9, delete the rest
  # This way after we create the new log, we'll have exactly 10
  ls -t repo_*.log 2>/dev/null | tail -n +10 | xargs -r rm -f
  cd "$BUILD_ROOT"
fi

TIMESTAMP=$(date +%Y%m%d_%H%M%S)
if [[ -n "$LOG_MIRROR" ]]; then
  LOG_FILE="$LOG_DIR/repo_${LOG_MIRROR}_${TIMESTAMP}.log"
else
  LOG_FILE="$LOG_DIR/repo_${TIMESTAMP}.log"
fi
export LOG_FILE
export OMARCHY_LOG_FILE="$LOG_FILE"

# Show usage
show_usage() {
  echo "Usage: $0 <command> [options]"
  echo ""
  echo "Commands:"
  echo "  release     Run complete workflow: build → sign → promote → clean → update → sync"
  echo "  build       Build packages (unsigned)"
  echo "  sign        Sign all packages in build-output"
  echo "  promote     Promote build to production (build-output → pkgs.omarchy.org)"
  echo "  update      Update repository database"
  echo "  clean       Clean old package versions"
  echo "  advance     Move packages forward through the pipeline (edge → rc → stable)"
  echo "  bootstrap-rc  One-time seed of the rc channel from stable"
  echo "  migrate     DEPRECATED alias for 'advance --from edge --to stable'"
  echo "  list        List source package metadata (use --repo for published repo)"
  echo "  remove      Remove a specific package"
  echo "  sync        Sync repository to remote"
  echo "  push        Upload local builds to the repository host and publish them there"
  echo "  deploy      Build locally, then push: one command from a build machine"
  echo "  setup       Install everything the repository host needs"
  echo "  timers      Show release timer schedule, last runs, and queued builds"
  echo ""
  echo "Typical workflows:"
  echo "  $0 release                  # Complete release workflow"
  echo ""
  echo "  $0 build                    # Manual step-by-step:"
  echo "  $0 sign"
  echo "  $0 promote"
  echo "  $0 clean"
  echo "  $0 update"
  echo "  $0 sync pkgs.omarchy.org/x86_64"
  echo ""
  echo "Remote control: when a repository host is configured (OMARCHY_REPO_HOST"
  echo "or .repo-host — any ssh destination), the commands above except list,"
  echo "push, deploy, and setup run ON the host over ssh. Pass --local to force"
  echo "execution on this machine instead."
  echo ""
  echo "For command-specific help, use:"
  echo "  $0 <command> --help"
  exit 0
}

# Check if no command provided
if [[ $# -eq 0 ]]; then
  show_usage
fi

# Get command and shift arguments
COMMAND="$1"
shift

# Route to appropriate script with logging
case $COMMAND in
release)
  "$SCRIPT_DIR/release" "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
build)
  "$SCRIPT_DIR/build" "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
sign)
  "$SCRIPT_DIR/sign" "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
promote)
  "$SCRIPT_DIR/promote-build" "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
update)
  "$SCRIPT_DIR/update-repo" "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
clean)
  "$SCRIPT_DIR/clean-repo" "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
advance)
  "$SCRIPT_DIR/advance-channel" "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
bootstrap-rc)
  "$SCRIPT_DIR/advance-channel" --from stable --to rc --bootstrap "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
migrate)
  print_warning "'migrate' is deprecated; releases now flow edge → rc → stable (bin/repo advance)"
  "$SCRIPT_DIR/advance-channel" --from edge --to stable "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
list)
  "$SCRIPT_DIR/list-packages" "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
remove)
  "$SCRIPT_DIR/remove-package" "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
sync)
  "$SCRIPT_DIR/sync-repo" "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
push)
  "$SCRIPT_DIR/push-build" "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
deploy)
  "$SCRIPT_DIR/deploy" "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
setup)
  "$SCRIPT_DIR/setup" "$@" 2>&1 | tee "$LOG_FILE"
  exit ${PIPESTATUS[0]}
  ;;
timers)
  # Status output, not a build step: show it, do not log it.
  "$SCRIPT_DIR/timers" "$@"
  exit $?
  ;;
-h | --help | help)
  show_usage
  ;;
*)
  print_error "Unknown command: $COMMAND"
  echo ""
  show_usage
  ;;
esac
