#!/usr/bin/env bash
# =============================================================================
# Changemaker Lite V2 — Build & Push to Gitea Registry
# Builds production Docker images, tags with commit SHA + latest, and pushes
# to the Gitea container registry at gitea.bnkops.com/admin.
#
# Usage:
#   ./scripts/build-and-push.sh [OPTIONS]
#
# Options:
#   --services a,b,c      Comma-separated list of services to build
#                         (default: api admin media-api nginx ccp-agent)
#   --no-push             Build only, skip push (verify builds work)
#   --tag TAG             Override commit SHA tag (default: git rev-parse --short HEAD)
#   --registry URL        Override registry (default: gitea.bnkops.com/admin)
#   --dry-run             Print commands without executing
#   --help                Show this help
#
# Prerequisites:
#   docker login gitea.bnkops.com
# =============================================================================
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"

# --- Defaults ---
REGISTRY="${GITEA_REGISTRY:-gitea.bnkops.com/admin}"
COMMIT_SHA="$(git -C "$PROJECT_DIR" rev-parse --short HEAD 2>/dev/null || echo "local")"
TAG="${COMMIT_SHA}"
SERVICES="api admin media-api nginx ccp-agent"
NO_PUSH=false
DRY_RUN=false

# --- Colors ---
if [[ -t 1 ]] && [[ -z "${NO_COLOR:-}" ]]; then
  RED='\033[0;31m'  GREEN='\033[0;32m'  YELLOW='\033[0;33m'
  BLUE='\033[0;34m' CYAN='\033[0;36m'   BOLD='\033[1m'  NC='\033[0m'
else
  RED='' GREEN='' YELLOW='' BLUE='' CYAN='' BOLD='' NC=''
fi

info()    { echo -e "${BLUE}[INFO]${NC}  $*"; }
success() { echo -e "${GREEN}[OK]${NC}    $*"; }
warn()    { echo -e "${YELLOW}[WARN]${NC}  $*"; }
error()   { echo -e "${RED}[ERROR]${NC} $*" >&2; }
run()     { if [[ "$DRY_RUN" == "true" ]]; then echo -e "${CYAN}[DRY-RUN]${NC} $*"; else "$@"; fi; }

# --- Arg parser ---
while [[ $# -gt 0 ]]; do
  case "$1" in
    --services)          SERVICES="${2//,/ }"; shift 2 ;;
    --no-push)           NO_PUSH=true; shift ;;
    --tag)               TAG="$2"; shift 2 ;;
    --registry)          REGISTRY="$2"; shift 2 ;;
    --dry-run)           DRY_RUN=true; shift ;;
    --help|-h)
      sed -n '2,30p' "$0" | grep '^#' | sed 's/^# \?//'
      exit 0 ;;
    *) error "Unknown option: $1"; exit 1 ;;
  esac
done

echo -e "${BOLD}Changemaker Lite — Build & Push${NC}"
echo "  Registry:  $REGISTRY"
echo "  Tag:       $TAG"
echo "  Services:  $SERVICES"
echo "  Push:      $([[ "$NO_PUSH" == "true" ]] && echo "no" || echo "yes")"
echo ""

# --- Build mapping: service → dockerfile + context ---
build_service() {
  local svc="$1"
  local image="$REGISTRY/changemaker-${svc}:${TAG}"
  local image_latest="$REGISTRY/changemaker-${svc}:latest"

  case "$svc" in
    api)
      info "Building api (Express + Prisma)..."
      run docker buildx build \
        --target production \
        --tag "${image}" \
        --tag "${image_latest}" \
        --load \
        "${PROJECT_DIR}/api"
      ;;
    admin)
      info "Building admin (React + Vite)..."
      run docker buildx build \
        --target production \
        --tag "${image}" \
        --tag "${image_latest}" \
        --load \
        "${PROJECT_DIR}/admin"
      ;;
    media-api)
      info "Building media-api (Fastify + FFmpeg)..."
      run docker buildx build \
        --target production \
        --file "${PROJECT_DIR}/api/Dockerfile.media" \
        --tag "${image}" \
        --tag "${image_latest}" \
        --load \
        "${PROJECT_DIR}/api"
      ;;
    nginx)
      info "Building nginx (reverse proxy)..."
      run docker buildx build \
        --tag "${image}" \
        --tag "${image_latest}" \
        --load \
        "${PROJECT_DIR}/nginx"
      ;;
    ccp-agent)
      info "Building ccp-agent (remote management agent)..."
      run docker buildx build \
        --tag "${image}" \
        --tag "${image_latest}" \
        --load \
        "${PROJECT_DIR}/changemaker-control-panel/agent"
      ;;
    *)
      error "Unknown service: $svc"
      return 1
      ;;
  esac

  success "Built ${svc} → ${image}"

  if [[ "$NO_PUSH" == "false" ]]; then
    info "Pushing ${svc}:${TAG}..."
    run docker push "${image}"
    run docker push "${image_latest}"
    success "Pushed ${svc}:${TAG} + :latest"
  fi
}

# --- Main ---
FAILED=()
for svc in $SERVICES; do
  if ! build_service "$svc"; then
    FAILED+=("$svc")
  fi
done

echo ""
if [[ ${#FAILED[@]} -eq 0 ]]; then
  if [[ "$NO_PUSH" == "true" ]]; then
    success "All services built (not pushed)."
  else
    success "All services built and pushed."
  fi
  echo ""
  if [[ "$NO_PUSH" == "false" ]]; then
    info "Images available in registry:"
    for svc in $SERVICES; do
      echo "  ${REGISTRY}/changemaker-${svc}:${TAG}"
    done
    echo ""
    info "To use these images: IMAGE_TAG=${TAG} docker compose pull ${SERVICES}"
    info "Or set IMAGE_TAG=${TAG} in .env"
  fi
else
  error "Failed services: ${FAILED[*]}"
  exit 1
fi
