#!/usr/bin/env bash
set -euo pipefail

show_help() {
  cat <<'EOF'
ARGUS Unified Build System - Image Build Tool

Usage: $0 [OPTIONS]

Options:
  --intranet        Use intranet mirror for log/bind builds
  --master-offline  Build master offline image (requires src/master/offline_wheels.tar.gz)
  --metric          Build metric module images (ftp, prometheus, grafana, test nodes)
  --no-cache        Build all images without using Docker layer cache
  -h, --help        Show this help message

Examples:
  $0                             # Build with default sources
  $0 --intranet                  # Build with intranet mirror
  $0 --master-offline            # Additionally build argus-master:offline
  $0 --metric                    # Additionally build metric module images
  $0 --intranet --master-offline --metric
EOF
}

use_intranet=false
build_master=true
build_master_offline=false
build_metric=true
no_cache=false

while [[ $# -gt 0 ]]; do
  case $1 in
    --intranet)
      use_intranet=true
      shift
      ;;
    --master)
      build_master=true
      shift
      ;;
    --master-offline)
      build_master=true
      build_master_offline=true
      shift
      ;;
    --metric)
      build_metric=true
      shift
      ;;
    --no-cache)
      no_cache=true
      shift
      ;;
    -h|--help)
      show_help
      exit 0
      ;;
    *)
      echo "Unknown option: $1" >&2
      show_help
      exit 1
      ;;
  esac
done

root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
. "$root/scripts/common/build_user.sh"

declare -a build_args=()

if [[ "$use_intranet" == true ]]; then
  build_args+=("--build-arg" "USE_INTRANET=true")
fi

cd "$root"

load_build_user
build_args+=("--build-arg" "ARGUS_BUILD_UID=${ARGUS_BUILD_UID}" "--build-arg" "ARGUS_BUILD_GID=${ARGUS_BUILD_GID}")

if [[ "$no_cache" == true ]]; then
  build_args+=("--no-cache")
fi

master_root="$root/src/master"
master_offline_tar="$master_root/offline_wheels.tar.gz"
master_offline_dir="$master_root/offline_wheels"

if [[ "$build_master_offline" == true ]]; then
  if [[ ! -f "$master_offline_tar" ]]; then
    echo "❌ offline wheels tar not found: $master_offline_tar" >&2
    echo "   请提前准备好 offline_wheels.tar.gz 后再执行 --master-offline" >&2
    exit 1
  fi
  echo "📦 Preparing offline wheels for master (extracting $master_offline_tar)"
  rm -rf "$master_offline_dir"
  mkdir -p "$master_offline_dir"
  tar -xzf "$master_offline_tar" -C "$master_root"
  has_wheel=$(find "$master_offline_dir" -maxdepth 1 -type f -name '*.whl' -print -quit)
  if [[ -z "$has_wheel" ]]; then
    echo "❌ offline_wheels extraction failed或无 wheel: $master_offline_dir" >&2
    exit 1
  fi
fi

echo "======================================="
echo "ARGUS Unified Build System"
echo "======================================="

if [[ "$use_intranet" == true ]]; then
  echo "🌐 Mode: Intranet (Using internal mirror: 10.68.64.1)"
else
  echo "🌐 Mode: Public (Using default package sources)"
fi

echo "👤 Build user UID:GID -> ${ARGUS_BUILD_UID}:${ARGUS_BUILD_GID}"

echo "📁 Build context: $root"
echo ""

build_image() {
  local image_name=$1
  local dockerfile_path=$2
  local tag=$3
  local context="."
  shift 3

  if [[ $# -gt 0 ]]; then
    context=$1
    shift
  fi

  local extra_args=("$@")

  echo "🔄 Building $image_name image..."
  echo "   Dockerfile: $dockerfile_path"
  echo "   Tag: $tag"
  echo "   Context: $context"

  if docker build "${build_args[@]}" "${extra_args[@]}" -f "$dockerfile_path" -t "$tag" "$context"; then
    echo "✅ $image_name image built successfully"
    return 0
  else
    echo "❌ Failed to build $image_name image"
    return 1
  fi
}

pull_base_image() {
  local image_ref=$1
  local attempts=${2:-3}
  local delay=${3:-5}

  for ((i=1; i<=attempts; i++)); do
    echo "   Pulling base image ($i/$attempts): $image_ref"
    if docker pull "$image_ref" >/dev/null; then
      echo "   Base image ready: $image_ref"
      return 0
    fi
    echo "   Pull failed: $image_ref"
    if (( i < attempts )); then
      echo "   Retrying in ${delay}s..."
      sleep "$delay"
    fi
  done

  echo "❌ Unable to pull base image after ${attempts} attempts: $image_ref"
  return 1
}

images_built=()
build_failed=false

if build_image "Elasticsearch" "src/log/elasticsearch/build/Dockerfile" "argus-elasticsearch:latest"; then
  images_built+=("argus-elasticsearch:latest")
else
  build_failed=true
fi

echo ""

if build_image "Kibana" "src/log/kibana/build/Dockerfile" "argus-kibana:latest"; then
  images_built+=("argus-kibana:latest")
else
  build_failed=true
fi

echo ""

if build_image "BIND9" "src/bind/build/Dockerfile" "argus-bind9:latest"; then
  images_built+=("argus-bind9:latest")
else
  build_failed=true
fi

echo ""

if [[ "$build_master" == true ]]; then
  echo ""
  echo "🔄 Building Master image..."
  pushd "$master_root" >/dev/null
  master_args=("--tag" "argus-master:latest")
  if [[ "$use_intranet" == true ]]; then
    master_args+=("--intranet")
  fi
  if [[ "$build_master_offline" == true ]]; then
    master_args+=("--offline")
  fi
  if [[ "$no_cache" == true ]]; then
    master_args+=("--no-cache")
  fi
  if ./scripts/build_images.sh "${master_args[@]}"; then
    if [[ "$build_master_offline" == true ]]; then
      images_built+=("argus-master:offline")
    else
      images_built+=("argus-master:latest")
    fi
  else
    build_failed=true
  fi
  popd >/dev/null
fi

if [[ "$build_metric" == true ]]; then
  echo ""
  echo "Building Metric module images..."

  metric_base_images=(
    "ubuntu:22.04"
    "ubuntu/prometheus:3-24.04_stable"
    "grafana/grafana:11.1.0"
  )

  for base_image in "${metric_base_images[@]}"; do
    if ! pull_base_image "$base_image"; then
      build_failed=true
    fi
  done

  metric_builds=(
    "Metric FTP|src/metric/ftp/build/Dockerfile|argus-metric-ftp:latest|src/metric/ftp/build"
    "Metric Prometheus|src/metric/prometheus/build/Dockerfile|argus-metric-prometheus:latest|src/metric/prometheus/build"
    "Metric Grafana|src/metric/grafana/build/Dockerfile|argus-metric-grafana:latest|src/metric/grafana/build"
  )

  for build_spec in "${metric_builds[@]}"; do
    IFS='|' read -r image_label dockerfile_path image_tag build_context <<< "$build_spec"
    if build_image "$image_label" "$dockerfile_path" "$image_tag" "$build_context"; then
      images_built+=("$image_tag")
    else
      build_failed=true
    fi
    echo ""
  done
fi

# =======================================
# Web & Alert module images
# =======================================

echo ""
echo "Building Web and Alert module images..."

# Pre-pull commonly used base images for stability
web_alert_base_images=(
  "node:20"
  "ubuntu:24.04"
)

for base_image in "${web_alert_base_images[@]}"; do
  if ! pull_base_image "$base_image"; then
    build_failed=true
  fi
done

web_builds=(
  "Web Frontend|src/web/build_tools/frontend/Dockerfile|argus-web-frontend:latest|."
  "Web Proxy|src/web/build_tools/proxy/Dockerfile|argus-web-proxy:latest|."
)

for build_spec in "${web_builds[@]}"; do
  IFS='|' read -r image_label dockerfile_path image_tag build_context <<< "$build_spec"
  if build_image "$image_label" "$dockerfile_path" "$image_tag" "$build_context"; then
    images_built+=("$image_tag")
  else
    build_failed=true
  fi
  echo ""
done

alert_builds=(
  "Alertmanager|src/alert/alertmanager/build/Dockerfile|argus-alertmanager:latest|."
)

for build_spec in "${alert_builds[@]}"; do
  IFS='|' read -r image_label dockerfile_path image_tag build_context <<< "$build_spec"
  if build_image "$image_label" "$dockerfile_path" "$image_tag" "$build_context"; then
    images_built+=("$image_tag")
  else
    build_failed=true
  fi
  echo ""
done

echo "======================================="
echo "📦 Build Summary"
echo "======================================="

if [[ ${#images_built[@]} -gt 0 ]]; then
  echo "✅ Successfully built images:"
  for image in "${images_built[@]}"; do
    echo "   • $image"
  done
fi

if [[ "$build_failed" == true ]]; then
  echo ""
  echo "❌ Some images failed to build. Please check the errors above."
  exit 1
fi

if [[ "$use_intranet" == true ]]; then
  echo ""
  echo "🌐 Built with intranet mirror configuration"
fi

if [[ "$build_master_offline" == true ]]; then
  echo ""
  echo "🧳 Master offline wheels 已解压到 $master_offline_dir"
fi
echo ""
echo "🚀 Next steps:"
echo "   ./build/save_images.sh --compress          # 导出镜像"
echo "   cd src/master/tests && MASTER_IMAGE_TAG=argus-master:offline ./scripts/00_e2e_test.sh"
echo ""
