#!/usr/bin/env bash
#
# build-image: one-shot build of the ZStack AIOS control-plane image from the
# workspace root. Builds the rebranded frontend, overlays it plus our patched
# backend sources onto the matching official release image, then (by default)
# smoke tests the result.
#
# It requires both forks to sit on the *same* v<version>-lofyer branch, so a
# build can never mix a frontend and backend from different upstream releases.
#
# Usage:
#   scripts/build-image                 # build + verify
#   scripts/build-image --no-verify     # build only
#   scripts/build-image --skip-ui-build # reuse existing frontend dist/
#   scripts/build-image --push          # push after a successful build
#   scripts/build-image --dry-run       # show what would happen
#
# Env knobs (also see gpustack-lofyer/hack/package-lofyer):
#   NAMESPACE / REPOSITORY / TAG / IMAGE / BASE_IMAGE
#   SMOKE_PORT   host port used by the smoke test (default 18080)
#
set -o errexit
set -o nounset
set -o pipefail

source "$(dirname "${BASH_SOURCE[0]}")/lib/common.sh"

UI_BUILD=1
VERIFY=1
PUSH=0
DRY_RUN=0
SMOKE_PORT="${SMOKE_PORT:-18080}"

while [[ $# -gt 0 ]]; do
  case "${1}" in
    --skip-ui-build) UI_BUILD=0 ;;
    --no-verify)     VERIFY=0 ;;
    --verify)        VERIFY=1 ;;
    --push)          PUSH=1 ;;
    --dry-run)       DRY_RUN=1 ;;
    -h|--help)       sed -n '2,26p' "${0}"; exit 0 ;;
    *)               fail "unknown argument: ${1}" ;;
  esac
  shift
done

require_cmd docker git
require_repos

VERSION="$(resolve_workspace_version)"
TAG="${TAG:-${VERSION}}"
IMAGE="${IMAGE:-${NAMESPACE}/${REPOSITORY}:${TAG}}"

log "workspace version : ${VERSION}"
log "target image      : ${IMAGE}"

# 1. Frontend.
step "Building frontend"
if [[ "${UI_BUILD}" == "1" ]]; then
  require_cmd npm
  if [[ "${DRY_RUN}" == "1" ]]; then
    echo "(dry-run) (cd ${UI_REPO} && GPUSTACK_UI_VERSION=${VERSION} npm run build)"
  else
    (cd "${UI_REPO}" && GPUSTACK_UI_VERSION="${VERSION}" npm run build)
  fi
else
  log "skipping frontend build (--skip-ui-build)"
  [[ -f "${UI_REPO}/dist/index.html" ]] \
    || fail "no existing frontend dist at ${UI_REPO}/dist (drop --skip-ui-build)"
fi

# 2. Image. Delegates to the backend packaging script, which stages the dist
#    and only the python files that differ from the upstream tag.
step "Building image ${IMAGE}"
PACK_ENV=(
  "NAMESPACE=${NAMESPACE}"
  "REPOSITORY=${REPOSITORY}"
  "TAG=${TAG}"
  "IMAGE=${IMAGE}"
  "UI_REPO=${UI_REPO}"
  "PUSH=${PUSH}"
  "DRY_RUN=${DRY_RUN}"
)
[[ -n "${BASE_IMAGE:-}" ]] && PACK_ENV+=("BASE_IMAGE=${BASE_IMAGE}")

env "${PACK_ENV[@]}" "${BACKEND_REPO}/hack/package-lofyer"

if [[ "${DRY_RUN}" == "1" ]]; then
  log "dry-run complete"
  exit 0
fi

# 3. Verify.
if [[ "${VERIFY}" == "1" ]]; then
  step "Verifying ${IMAGE}"
  IMAGE="${IMAGE}" SMOKE_PORT="${SMOKE_PORT}" "$(dirname "${BASH_SOURCE[0]}")/verify-image"
fi

step "Done"
log "image: ${IMAGE}"
log "run it with:"
echo "  docker run -d --name zstack-aios -p 80:80 -v /var/run/docker.sock:/var/run/docker.sock ${IMAGE}"
