#!/usr/bin/env bash
# =============================================================================
# felhom-hub — Docker image build script
# =============================================================================
# CANONICAL LOCATION: felhom.eu/scripts/build-hub.sh (this file, in git).
# OPERATIVE LOCATION: /mnt/5_hdd/felhom.eu/build/felhom-hub/build.sh — a SYMLINK to this file, so
# there is exactly one source of truth and a repo edit is live immediately (the install_skills.py
# pattern). It lived ONLY in that build dir until v1.23.0, outside any repo and therefore
# unversioned, unreviewed and unrecoverable — noted as a follow-up in felhom.eu/REPORT.md §6.
#
# Copies hub/ source from the felhom.eu git repo, builds the Docker image. Build artifacts stay in
# the build dir's workspace/ — the git repo stays clean.
#
# Usage:
#   ./build.sh                    # Build for current platform, tag as :dev
#   ./build.sh 0.1.0              # Build with version tag
#   ./build.sh 0.1.0 --push       # Build + push to Gitea registry
#   ./build.sh 0.1.0 --multiarch  # Build amd64+arm64 + push
# =============================================================================
set -euo pipefail

SCRIPT_VERSION="1.23.0"

# --- Configuration (edit these if your paths differ) ---
REPO_DIR="/mnt/5_hdd/felhom.eu/git/felhom.eu"
HUB_SRC="${REPO_DIR}/hub"
REGISTRY="gitea.dooplex.hu/admin"
IMAGE="${REGISTRY}/felhom-hub"

# Build workspace — a temp directory next to this script, NOT in the git repo
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
BUILD_DIR="${SCRIPT_DIR}/workspace"

# --- Parse arguments ---
VERSION="${1:-dev}"
ACTION="${2:-}"  # --push or --multiarch

# --- Colors ---
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
info()  { echo -e "${GREEN}[INFO]${NC}  $*"; }
warn()  { echo -e "${YELLOW}[WARN]${NC}  $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; }
step()  { echo -e "${CYAN}[STEP]${NC}  $*"; }

# --- Pre-flight checks ---
if [[ ! -d "${HUB_SRC}" ]]; then
    error "Hub source not found: ${HUB_SRC}"
    error "Clone the repo first: git clone https://gitea.dooplex.hu/admin/felhom.eu.git ${REPO_DIR}"
    exit 1
fi

if ! command -v docker &>/dev/null; then
    error "Docker not found."
    exit 1
fi

# Get git commit for build metadata
GIT_COMMIT=$(cd "${REPO_DIR}" && git rev-parse --short HEAD 2>/dev/null || echo "unknown")

echo ""
info "╔══════════════════════════════════════╗"
info "║  felhom-hub build                    ║"
info "╚══════════════════════════════════════╝"
info "Version:  ${VERSION}   (build-hub.sh v${SCRIPT_VERSION})"
info "Commit:   ${GIT_COMMIT}"
info "Source:   ${HUB_SRC}"
info "Build:    ${BUILD_DIR}"
info "Image:    ${IMAGE}:${VERSION}"
echo ""

# =========================================================================
# Step 1: Pull latest code
# =========================================================================
step "1/3 — Pulling latest code..."

cd "${REPO_DIR}"
git pull --ff-only 2>/dev/null || warn "git pull failed (offline or dirty tree?)"

# =========================================================================
# Step 2: Sync source to build workspace
# =========================================================================
step "2/3 — Syncing source to workspace..."

mkdir -p "${BUILD_DIR}"

rsync -a --delete \
    --exclude '.git' \
    --exclude 'bin/' \
    --exclude '*.exe' \
    "${HUB_SRC}/" "${BUILD_DIR}/"

info "Source synced to ${BUILD_DIR}"

# Sync app assets from website directory into build workspace
WEBSITE_ASSETS_DIR="${REPO_DIR}/website/assets"
if [[ -d "${WEBSITE_ASSETS_DIR}" ]]; then
    mkdir -p "${BUILD_DIR}/assets"
    cp "${WEBSITE_ASSETS_DIR}"/*-logo.svg "${BUILD_DIR}/assets/" 2>/dev/null || true
    cp "${WEBSITE_ASSETS_DIR}"/*-logo.png "${BUILD_DIR}/assets/" 2>/dev/null || true
    cp "${WEBSITE_ASSETS_DIR}"/*-screenshot-*.webp "${BUILD_DIR}/assets/" 2>/dev/null || true
    ASSET_COUNT=$(ls "${BUILD_DIR}/assets/" 2>/dev/null | wc -l)
    info "App assets synced (${ASSET_COUNT} files)"
else
    warn "Website assets dir not found: ${WEBSITE_ASSETS_DIR}"
    mkdir -p "${BUILD_DIR}/assets"
fi

# Verify structure
cd "${BUILD_DIR}"

for dir in cmd/hub internal/api internal/store internal/web; do
    if [[ ! -d "${dir}" ]]; then
        error "Missing expected directory: ${dir}"
        error "Hub source structure may be incomplete."
        exit 1
    fi
done
info "Package structure verified ✓"

if [[ ! -f "go.mod" ]]; then
    error "go.mod not found in build workspace!"
    exit 1
fi

# Ensure go.sum exists (Dockerfile COPY will fail without it)
if command -v go &>/dev/null; then
    info "Running go mod tidy..."
    go mod tidy 2>&1 || warn "go mod tidy had issues (Docker build may still work)"
elif [[ ! -f "go.sum" ]]; then
    warn "go.sum missing and Go not installed locally — creating empty go.sum"
    warn "(Docker build stage will resolve dependencies via 'go mod download')"
    touch go.sum
fi

# =========================================================================
# Step 3: Docker build
# =========================================================================
step "3/3 — Building Docker image..."

BUILD_ARGS=(
    --build-arg "VERSION=${VERSION}"
    --build-arg "BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
)

case "${ACTION}" in
    --push)
        info "Building for current platform + pushing..."
        docker build "${BUILD_ARGS[@]}" \
            -t "${IMAGE}:${VERSION}" \
            -t "${IMAGE}:latest" \
            .

        info "Pushing..."
        docker push "${IMAGE}:${VERSION}"
        docker push "${IMAGE}:latest"
        ;;

    --multiarch)
        info "Building multi-arch (amd64 + arm64) + pushing..."

        # Ensure buildx builder exists
        if ! docker buildx inspect felhom-builder &>/dev/null; then
            info "Creating buildx builder (one-time setup)..."
            docker buildx create --name felhom-builder --use --bootstrap
        else
            docker buildx use felhom-builder
        fi

        docker buildx build "${BUILD_ARGS[@]}" \
            --platform linux/amd64,linux/arm64 \
            -t "${IMAGE}:${VERSION}" \
            -t "${IMAGE}:latest" \
            --push \
            .
        ;;

    *)
        info "Building for current platform (local only)..."
        docker build "${BUILD_ARGS[@]}" \
            -t "${IMAGE}:${VERSION}" \
            -t "${IMAGE}:latest" \
            .
        ;;
esac

# =========================================================================
# Summary
# =========================================================================
echo ""
info "╔══════════════════════════════════════╗"
info "║  Build complete ✓                    ║"
info "╚══════════════════════════════════════╝"
info "Image: ${IMAGE}:${VERSION}"

# Show image size if available locally
SIZE=$(docker image inspect "${IMAGE}:${VERSION}" --format='{{.Size}}' 2>/dev/null || echo "")
if [[ -n "${SIZE}" ]]; then
    SIZE_HUMAN=$(numfmt --to=iec "${SIZE}" 2>/dev/null || echo "${SIZE} bytes")
    info "Size:  ${SIZE_HUMAN}"
fi

echo ""
if [[ "${ACTION}" == "" ]]; then
    info "Image is local only. To push: ./build.sh ${VERSION} --push"
else
    info "Image pushed to registry."
    echo ""
    info "Deploy to k3s — GitOps ONLY. The manifest in git is the source of truth:"
    info "  1. bump the image tag in ${REPO_DIR}/manifests/hub.yaml to ${VERSION}, commit, push"
    info "  2. hard-refresh + sync the ArgoCD app (auto-sync is OFF — the sync is deliberate):"
    info "     sudo kubectl -n argocd annotate application felhom argocd.argoproj.io/refresh=hard --overwrite"
    info "     sudo kubectl -n argocd patch application felhom --type merge \\"
    info "       -p '"'"'{\"operation\":{\"initiatedBy\":{\"username\":\"cc\"},\"sync\":{\"syncStrategy\":{\"apply\":{}}}}}'"'"'"
    info ""
    info "  NEVER \`kubectl set image\` or \`kubectl apply\` by hand — ArgoCD reverts it on the next"
    info "  sync, so the change looks applied, works for a while, and then silently disappears."
fi
echo ""
