#!/bin/bash

# Safer bash: we manage errors manually (no -e) but detect pipeline failures
set -o pipefail

# Quiet mode default; enable verbose with --verbose
QUIET=${QUIET:-true}

# Parse --verbose early (we'll reparse fully later as well)
for arg in "$@"; do
  if [[ "$arg" == "--verbose" ]]; then QUIET=false; fi
done

# Per-run logs directory
RUN_TS=$(date +%Y%m%d_%H%M%S)
LOG_DIR="./build_logs/$RUN_TS"
mkdir -p "$LOG_DIR"

# Error aggregation
ERRORS=()
ERROR_LINES=()
EXIT_CODE=0

# Helper: run_quiet SERVICE STEP -- CMD ARGS...
run_quiet() {
  local SERVICE="$1"; shift
  local STEP="$1"; shift
  # Expect a literal "--" separator before the command
  if [[ "$1" == "--" ]]; then shift; fi
  local LOG_FILE="$LOG_DIR/${SERVICE}.${STEP}.log"
  if [[ "$QUIET" == "true" ]]; then
    "$@" > /dev/null 2> >(tee -a "$LOG_FILE" >&2)
  else
    "$@" > >(tee -a "$LOG_FILE") 2> >(tee -a "$LOG_FILE" >&2)
  fi
  local RC=$?
  echo "$LOG_FILE" > "$LOG_DIR/.last_${SERVICE}_${STEP}.path"
  return $RC
}

record_error() {
  local SERVICE="$1"; local STEP="$2"; local MESSAGE="$3"; local LOG_FILE="$4"
  ERRORS+=("$SERVICE|$STEP|$LOG_FILE|$MESSAGE")
  ERROR_LINES+=("$MESSAGE")
  EXIT_CODE=1
}

source ./podman_env_switch.sh dev

# Load environment variables
source .env

# Check if podman is available
if ! command -v podman &> /dev/null; then
    echo "Error: podman not found"
    exit 1
fi

echo "Using container runtime: podman"

# Local registry
REGISTRY="registry.ask-eve-ai-local.com"
# Account prefix voor consistency met Docker Hub
ACCOUNT="josakola"

# Tag (you might want to use a version or git commit hash)
TAG="latest"

# Single platform - AMD64 only for simplicity
PLATFORM="linux/amd64"

# Default action
ACTION="both"

# Default build options
NO_CACHE=""
PROGRESS=""
DEBUG=""
BUILD_BASE=""
BASE_ONLY=""

# Function to display usage information
usage() {
    echo "Usage: $0 [-b|-p|-bb|--base-only] [--no-cache] [--progress=plain] [--debug] [--verbose] [service1 service2 ...]"
    echo "  -b: Build only"
    echo "  -p: Push only"
    echo "  -bb: Build base image (in addition to services)"
    echo "  --base-only: Build only base image (skip services)"
    echo "  --no-cache: Perform a clean build without using cache"
    echo "  --progress=plain: Show detailed progress of the build"
    echo "  --debug: Enable debug mode for the build"
    echo "  --verbose: Show full output of build/push (default is quiet; logs always saved under ./build_logs/<timestamp>)"
    echo "  If no option is provided, both build and push will be performed."
    echo "  If no services are specified, all eveai_ services and nginx will be processed."
    echo "  All images are built for AMD64 platform (compatible with both x86_64 and Apple Silicon via emulation)."
}

# Parse command-line options
while [[ $# -gt 0 ]]; do
    case $1 in
        --verbose)
            QUIET=false
            shift
            ;;
        -b)
            ACTION="build"
            shift
            ;;
        -p)
            ACTION="push"
            shift
            ;;
        -bb)
            BUILD_BASE="true"
            shift
            ;;
        --base-only)
            BASE_ONLY="true"
            shift
            ;;
        --no-cache)
            NO_CACHE="--no-cache"
            shift
            ;;
        --progress=plain)
            PROGRESS="--progress=plain"
            shift
            ;;
        --debug)
            DEBUG="--debug"
            shift
            ;;
        -*)
            echo "Unknown option: $1"
            usage
            exit 1
            ;;
        *)
            break
            ;;
    esac
done

# Function to build base image
build_base_image() {
    echo "🏗️  Building base image... =============================================================="
    local BASE_IMAGE_NAME="$REGISTRY/$ACCOUNT/eveai-base:$TAG"
    
    echo "Building base image for platform: $PLATFORM"
    echo "Base image tag: $BASE_IMAGE_NAME"
    
    run_quiet base build -- podman build \
        --platform "$PLATFORM" \
        $NO_CACHE \
        $PROGRESS \
        $DEBUG \
        -t "$ACCOUNT/eveai-base:$TAG" \
        -t "$BASE_IMAGE_NAME" \
        -f Dockerfile.base \
        ..
    if [ $? -ne 0 ]; then
        LOG_FILE="$LOG_DIR/base.build.log"
        echo "❌ Failed to build base image"
        record_error base build "❌ Failed to build base image" "$LOG_FILE"
        return 1
    fi

    if [ "$ACTION" = "push" ] || [ "$ACTION" = "both" ]; then
        echo "Pushing base image to registry..."
        run_quiet base push -- podman push "$BASE_IMAGE_NAME"
        if [ $? -ne 0 ]; then
            LOG_FILE="$LOG_DIR/base.push.log"
            echo "❌ Failed to push base image"
            record_error base push "❌ Failed to push base image" "$LOG_FILE"
            return 1
        fi
    fi

    echo "✅ Base image built successfully"
}

# Function to check if we should build base image
should_build_base() {
    if [ "$BUILD_BASE" = "true" ] || [ "$BASE_ONLY" = "true" ]; then
        return 0  # true
    else
        return 1  # false
    fi
}

# Function to build and/or push a service
process_service() {
    local SERVICE="$1"
    echo "Processing $SERVICE... =================================================================="

    # Extract the build context and dockerfile from the compose file
    CONTEXT=$(yq e ".services.$SERVICE.build.context" compose_dev.yaml)
    DOCKERFILE=$(yq e ".services.$SERVICE.build.dockerfile" compose_dev.yaml)

    # Check if context directory exists
    if [ ! -d "$CONTEXT" ]; then
        echo "Error: Build context directory '$CONTEXT' for service '$SERVICE' does not exist."
        return 1
    fi

    # Check if Dockerfile exists
    if [ ! -f "$CONTEXT/$DOCKERFILE" ]; then
        echo "Error: Dockerfile '$DOCKERFILE' for service '$SERVICE' does not exist in context '$CONTEXT'."
        return 1
    fi

    # Construct image names
    LOCAL_IMAGE_NAME="$ACCOUNT/$SERVICE:$TAG"
    REGISTRY_IMAGE_NAME="$REGISTRY/$ACCOUNT/$SERVICE:$TAG"

    echo "Building for platform: $PLATFORM"
    echo "Local tag: $LOCAL_IMAGE_NAME"
    echo "Registry tag: $REGISTRY_IMAGE_NAME"

    # Build and/or push based on ACTION
    if [ "$ACTION" = "build" ]; then
        echo "🛠️ Building $SERVICE for $PLATFORM..."
        run_quiet "$SERVICE" build -- podman build \
            --platform "$PLATFORM" \
            $NO_CACHE \
            $PROGRESS \
            $DEBUG \
            -t "$LOCAL_IMAGE_NAME" \
            -t "$REGISTRY_IMAGE_NAME" \
            -f "$CONTEXT/$DOCKERFILE" \
            "$CONTEXT"
        if [ $? -ne 0 ]; then
            LOG_FILE="$LOG_DIR/${SERVICE}.build.log"
            echo "❌ Failed to build $SERVICE"
            record_error "$SERVICE" build "❌ Failed to build $SERVICE" "$LOG_FILE"
            return 1
        fi

    elif [ "$ACTION" = "push" ]; then
        echo "📤 Pushing $SERVICE to registry..."
        run_quiet "$SERVICE" push -- podman push "$REGISTRY_IMAGE_NAME"
        if [ $? -ne 0 ]; then
            LOG_FILE="$LOG_DIR/${SERVICE}.push.log"
            echo "❌ Failed to push $SERVICE"
            record_error "$SERVICE" push "❌ Failed to push $SERVICE" "$LOG_FILE"
            return 1
        fi

    else
        # Both build and push
        echo "🛠️ Building $SERVICE for $PLATFORM..."
        run_quiet "$SERVICE" build -- podman build \
            --platform "$PLATFORM" \
            $NO_CACHE \
            $PROGRESS \
            $DEBUG \
            -t "$LOCAL_IMAGE_NAME" \
            -t "$REGISTRY_IMAGE_NAME" \
            -f "$CONTEXT/$DOCKERFILE" \
            "$CONTEXT"
        if [ $? -ne 0 ]; then
            LOG_FILE="$LOG_DIR/${SERVICE}.build.log"
            echo "❌ Failed to build $SERVICE"
            record_error "$SERVICE" build "❌ Failed to build $SERVICE" "$LOG_FILE"
            return 1
        fi

        echo "📤 Pushing $SERVICE to registry..."
        run_quiet "$SERVICE" push -- podman push "$REGISTRY_IMAGE_NAME"
        if [ $? -ne 0 ]; then
            LOG_FILE="$LOG_DIR/${SERVICE}.push.log"
            echo "❌ Failed to push $SERVICE"
            record_error "$SERVICE" push "❌ Failed to push $SERVICE" "$LOG_FILE"
            return 1
        fi
    fi
}

# If no arguments are provided, process all services
if [ $# -eq 0 ]; then
    SERVICES=()
    while IFS= read -r line; do
        SERVICES+=("$line")
    done < <(yq e '.services | keys | .[]' compose_dev.yaml | grep -E '^(nginx|eveai_|prometheus|grafana)')
else
    SERVICES=("$@")
fi

# Handle base-only mode
if [ "$BASE_ONLY" = "true" ]; then
    echo "🎯 Base-only mode: Building only base image"
    build_base_image
    echo -e "\033[32m✅ Base image build completed!\033[0m"
    exit 0
fi

# Build base image if requested
if should_build_base; then
    build_base_image
    echo ""  # Empty line for readability
fi

echo "Using simplified AMD64-only approach for maximum compatibility..."
echo "Images will be tagged as: $REGISTRY/$ACCOUNT/[service]:$TAG"

# Reorder to ensure nginx builds before eveai_* if both are present
HAS_NGINX=false
HAS_APPS=false
for S in "${SERVICES[@]}"; do
  if [[ "$S" == "nginx" ]]; then HAS_NGINX=true; fi
  if [[ "$S" == eveai_* ]]; then HAS_APPS=true; fi
done

if $HAS_NGINX && $HAS_APPS; then
  ORDERED_SERVICES=("nginx")
  for S in "${SERVICES[@]}"; do
    if [[ "$S" != "nginx" ]]; then ORDERED_SERVICES+=("$S"); fi
  done
  SERVICES=("${ORDERED_SERVICES[@]}")
fi

# Loop through services
for SERVICE in "${SERVICES[@]}"; do
    if [[ "$SERVICE" == "nginx" ]]; then
      run_quiet nginx copy-specialist-svgs -- ./copy_specialist_svgs.sh ../config ../nginx/static/assets
      if [ $? -ne 0 ]; then
        LOG_FILE="$LOG_DIR/nginx.copy-specialist-svgs.log"
        echo "⚠️ copy_specialist_svgs.sh not found or failed"
        record_error nginx copy-specialist-svgs "⚠️ copy_specialist_svgs.sh not found or failed" "$LOG_FILE"
      fi
      run_quiet nginx rebuild-chat-client -- ./rebuild_chat_client.sh
      if [ $? -ne 0 ]; then
        LOG_FILE="$LOG_DIR/nginx.rebuild-chat-client.log"
        echo "❌ rebuild_chat_client.sh failed"
        record_error nginx rebuild-chat-client "❌ rebuild_chat_client.sh failed" "$LOG_FILE"
      fi
      MANIFEST_SRC="../nginx/static/dist/manifest.json"
      MANIFEST_DST_DIR="../config/static-manifest"
      MANIFEST_DST="$MANIFEST_DST_DIR/manifest.json"
      if [ ! -f "$MANIFEST_SRC" ]; then
        if $HAS_NGINX; then
          echo "⚠️  manifest.json not found at $MANIFEST_SRC yet. nginx should be built first in this run."
        else
          echo "❌ manifest.json not found at $MANIFEST_SRC. Please build nginx (assets) first."
          exit 1
        fi
      fi
      mkdir -p "$MANIFEST_DST_DIR"
      if [ -f "$MANIFEST_SRC" ]; then
        cp -f "$MANIFEST_SRC" "$MANIFEST_DST"
        echo "📄 Staged manifest at $MANIFEST_DST"
      fi
    fi

    if [[ "$SERVICE" == "nginx" || "$SERVICE" == eveai_* || "$SERVICE" == "prometheus" || "$SERVICE" == "grafana" ]]; then
        if process_service "$SERVICE"; then
            echo "✅ Successfully processed $SERVICE"
        else
            echo "❌ Failed to process $SERVICE"
            ERROR_LINES+=("❌ Failed to process $SERVICE")
            EXIT_CODE=1
        fi
    else
        echo "⏭️  Skipping $SERVICE as it's not nginx, prometheus, grafana or doesn't start with eveai_"
    fi
done

if [ ${#ERRORS[@]} -eq 0 ]; then
  echo -e "\033[32m✅ All specified services processed successfully!\033[0m"
  echo -e "\033[32m📦 Images are available locally and in registry\033[0m"
else
  echo -e "\033[31m❌ One or more errors occurred during build/push\033[0m"
  # Reprint short failure lines (your concise messages)
  for LINE in "${ERROR_LINES[@]}"; do
    echo "$LINE"
  done
  echo ""
  echo "Details (see logs for full output):"
  for ITEM in "${ERRORS[@]}"; do
    SERVICE_STEP_MSG_LOG=$(echo "$ITEM")
    IFS='|' read -r SVC STEP LOGFILE MSG <<< "$SERVICE_STEP_MSG_LOG"
    echo "- Service: $SVC | Step: $STEP"
    echo "  ↳ Log: $LOGFILE"
  done
  EXIT_CODE=1
fi
# Always print finished timestamp
echo -e "\033[32m🕐 Finished at $(date +"%d/%m/%Y %H:%M:%S")\033[0m"
exit $EXIT_CODE