#!/usr/bin/env bash
# build-airgap.sh — pulls GitLab Docker images and packages everything
# into a self-contained tarball for offline deployment.
#
# Usage:
#   ./build-airgap.sh [GITLAB_VERSION]
#
# Examples:
#   ./build-airgap.sh                        # uses default version below
#   ./build-airgap.sh 17.10.1-ce.0
#
# Output:
#   gitlab-<version>-<date>.tar.gz
set -euo pipefail

###############################################################################
# Config
###############################################################################
DEFAULT_GITLAB_VERSION="17.10.1-ce.0"
GITLAB_VERSION="${1:-${DEFAULT_GITLAB_VERSION}}"
GITLAB_IMAGE="gitlab/gitlab-ce:${GITLAB_VERSION}"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUNDLE_DIR="${SCRIPT_DIR}/bundle"
IMAGES_DIR="${BUNDLE_DIR}/images"
DATESTAMP="$(date +%Y%m%d)"
OUTPUT_NAME="gitlab-${GITLAB_VERSION}-${DATESTAMP}.tar.gz"
OUTPUT_PATH="${SCRIPT_DIR}/${OUTPUT_NAME}"

###############################################################################
# Helpers
###############################################################################
info()  { echo -e "\033[1;34m[INFO]\033[0m  $*"; }
ok()    { echo -e "\033[1;32m[ OK ]\033[0m  $*"; }
die()   { echo -e "\033[1;31m[ERR ]\033[0m  $*" >&2; exit 1; }

###############################################################################
# Prereq checks
###############################################################################
check_prereqs() {
  command -v docker  >/dev/null 2>&1 || die "docker not found on PATH."
  docker info        >/dev/null 2>&1 || die "Docker daemon not reachable."
  command -v gzip    >/dev/null 2>&1 || die "gzip not found on PATH."
  command -v tar     >/dev/null 2>&1 || die "tar not found on PATH."
  ok "Prerequisites OK."
}

###############################################################################
# Pull images
###############################################################################
pull_images() {
  info "Pulling ${GITLAB_IMAGE}..."
  docker pull "${GITLAB_IMAGE}"
  ok "Pulled ${GITLAB_IMAGE}"
}

###############################################################################
# Save images to bundle/images/
###############################################################################
save_images() {
  mkdir -p "${IMAGES_DIR}"

  # Clean up any previously saved images so the bundle stays minimal
  rm -f "${IMAGES_DIR}"/*.tar.gz "${IMAGES_DIR}"/*.tar

  local safe_tag
  safe_tag="$(echo "${GITLAB_VERSION}" | tr '/: ' '---')"
  local archive="${IMAGES_DIR}/gitlab-ce-${safe_tag}.tar.gz"

  info "Saving ${GITLAB_IMAGE} → $(basename "${archive}")  (this can take a few minutes)..."
  docker save "${GITLAB_IMAGE}" | gzip -9 > "${archive}"

  local size
  size="$(du -sh "${archive}" | cut -f1)"
  ok "Saved ${archive}  (${size})"
}

###############################################################################
# Stamp the version into .env.example so ctl picks it up automatically
###############################################################################
stamp_version() {
  local env_example="${BUNDLE_DIR}/.env.example"
  sed -i "s|^GITLAB_VERSION=.*|GITLAB_VERSION=${GITLAB_VERSION}|" "${env_example}"
  ok "Stamped GITLAB_VERSION=${GITLAB_VERSION} into .env.example"
}

###############################################################################
# Make scripts executable
###############################################################################
fix_permissions() {
  chmod +x "${BUNDLE_DIR}/compose"
}

###############################################################################
# Package everything
###############################################################################
package() {
  info "Creating tarball ${OUTPUT_NAME}..."

  local top_dir="gitlab-${GITLAB_VERSION}"
  tar -czf "${OUTPUT_PATH}" \
    --transform "s|^bundle|${top_dir}|" \
    -C "${SCRIPT_DIR}" \
    bundle

  local size
  size="$(du -sh "${OUTPUT_PATH}" | cut -f1)"
  ok "Created ${OUTPUT_PATH}  (${size})"
}

###############################################################################
# Print final instructions
###############################################################################
print_instructions() {
  local top_dir="gitlab-${GITLAB_VERSION}"
  echo
  echo "=========================================="
  echo "  Build complete!"
  echo "=========================================="
  echo
  echo "  Distribute:  ${OUTPUT_PATH}"
  echo
  echo "  On the target machine:"
  echo "    1.  tar -xzf ${OUTPUT_NAME}"
  echo "    2.  cd ${top_dir}"
  echo "    3.  ./compose bootstrap"
  echo
  echo "  Other commands:"
  echo "    ./compose start | stop | logs | status"
  echo "    ./compose upgrade --from <old-dir>"
  echo
}

###############################################################################
# Main
###############################################################################
main() {
  echo "=========================================="
  echo "  GitLab Bundle Builder"
  echo "  Version: ${GITLAB_VERSION}"
  echo "=========================================="
  check_prereqs
  pull_images
  save_images
  stamp_version
  fix_permissions
  package
  print_instructions
}

main "$@"
