#!/bin/bash

# Abort if anything fails
set -e

# Source common functions
BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..")
source "$BUILD_ROOT/lib/message-helpers.sh"

# Configuration
BUILD_DIR="$BUILD_ROOT/build"
OUTPUT_DIR="$BUILD_ROOT/output/ruby"

# Default values
ARCHITECTURES=("x86_64")
RUBY_VERSIONS=()
RAILS_VERSIONS=("8.0.2.1")  # Current stable Rails version

# Function to fetch last N Ruby releases
fetch_ruby_releases() {
  local count=$1
  print_info "Fetching last $count Ruby releases..."
  
  # Fetch releases from Ruby's release page
  curl -s https://api.github.com/repos/ruby/ruby/releases | \
    jq -r '.[].tag_name' | \
    grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | \
    sed 's/^v//' | \
    head -n "$count"
}

# Parse command line arguments
while [[ $# -gt 0 ]]; do
  case $1 in
  --ruby)
    IFS=',' read -ra RUBY_VERSIONS <<< "$2"
    shift 2
    ;;
  --rails)
    IFS=',' read -ra RAILS_VERSIONS <<< "$2"
    shift 2
    ;;
  --arch)
    IFS=',' read -ra ARCHITECTURES <<< "$2"
    shift 2
    ;;
  --last)
    # Fetch last N Ruby releases
    RUBY_VERSIONS=($(fetch_ruby_releases "$2"))
    shift 2
    ;;
  -h | --help)
    echo "Usage: $0 [OPTIONS]"
    echo ""
    echo "Options:"
    echo "  --ruby <versions>   Comma-separated Ruby versions (e.g., 3.4.5,3.3.0,edge)"
    echo "  --rails <versions>  Comma-separated Rails versions (e.g., 8.0.2.1,7.2.0,edge)"
    echo "  --arch <archs>      Comma-separated architectures (e.g., x86_64,aarch64)"
    echo "  --last <n>          Build last N Ruby releases"
    echo "  -h, --help          Show this help message"
    echo ""
    echo "Examples:"
    echo "  $0 --ruby 3.4.5,edge --rails 8.0.2.1"
    echo "  $0 --last 10 --rails 8.0.2.1"
    echo "  $0 --ruby 3.4.5 --rails 8.0.2.1,7.2.0 --arch x86_64,aarch64"
    echo ""
    echo "Default behavior:"
    echo "  - Builds Ruby 3.4.5, edge, and last 10 releases"
    echo "  - Uses Rails 8.0.2.1"
    echo "  - Builds for x86_64 architecture"
    exit 0
    ;;
  *)
    print_error "Unknown option: $1"
    exit 1
    ;;
  esac
done

# If no Ruby versions specified, use defaults
if [[ ${#RUBY_VERSIONS[@]} -eq 0 ]]; then
  print_info "No Ruby versions specified, using defaults..."
  # Get last 10 releases
  LAST_10=($(fetch_ruby_releases 10))
  # Combine with specific versions
  RUBY_VERSIONS=("3.4.5" "edge" "${LAST_10[@]}")
  # Remove duplicates
  RUBY_VERSIONS=($(echo "${RUBY_VERSIONS[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
fi

print_header "Ruby Bundle Builder"
print_info "Ruby versions: ${RUBY_VERSIONS[*]}"
print_info "Rails versions: ${RAILS_VERSIONS[*]}"
print_info "Architectures: ${ARCHITECTURES[*]}"

# Check for Docker
if ! command -v docker &>/dev/null; then
  print_error "Docker is not installed"
  exit 1
fi

# Check if Docker daemon is running
if ! docker info &>/dev/null; then
  print_error "Docker daemon is not running"
  print_warning "Start Docker with: sudo systemctl start docker"
  exit 1
fi

# Setup QEMU for multi-platform builds if aarch64 is requested
if [[ " ${ARCHITECTURES[@]} " =~ " aarch64 " ]]; then
  print_info "Setting up QEMU for aarch64 emulation..."
  
  # Install QEMU user static for cross-platform emulation
  if ! docker run --rm --privileged multiarch/qemu-user-static --reset -p yes; then
    print_warning "Failed to setup QEMU, aarch64 builds may fail"
    print_info "You may need to install qemu-user-static on your host"
  else
    print_success "QEMU emulation enabled for multi-arch builds"
  fi
fi

# Create output directories
for arch in "${ARCHITECTURES[@]}"; do
  mkdir -p "$OUTPUT_DIR/$arch"
done

# Build the Docker image using buildx for multi-platform support
print_info "Building Docker image..."

# Determine platforms needed
PLATFORMS=""
for arch in "${ARCHITECTURES[@]}"; do
  case "$arch" in
    x86_64)
      [[ -n "$PLATFORMS" ]] && PLATFORMS+=","
      PLATFORMS+="linux/amd64"
      ;;
    aarch64)
      [[ -n "$PLATFORMS" ]] && PLATFORMS+=","
      PLATFORMS+="linux/arm64"
      ;;
    *)
      print_error "Unsupported architecture: $arch"
      continue
      ;;
  esac
done

# Use buildx to build multi-platform image
if command -v docker buildx &>/dev/null; then
  # Ensure we have a builder instance
  BUILDER_NAME="ruby-multiarch"
  if ! docker buildx ls | grep -q "$BUILDER_NAME"; then
    print_info "Creating buildx builder instance..."
    docker buildx create --name "$BUILDER_NAME" --driver docker-container --use
  else
    docker buildx use "$BUILDER_NAME"
  fi
  
  print_info "Building multi-platform image for: $PLATFORMS"
  
  # Build for all platforms at once
  # We can't use --load with multiple platforms, so we build separately for each
  for arch in "${ARCHITECTURES[@]}"; do
    case "$arch" in
      x86_64)
        PLATFORM="linux/amd64"
        ;;
      aarch64)
        PLATFORM="linux/arm64"
        ;;
    esac
    
    print_info "Building for $arch ($PLATFORM)..."
    if ! docker buildx build \
      --platform "$PLATFORM" \
      -t "ruby-builder:$arch" \
      --load \
      -f "$BUILD_DIR/Dockerfile.ruby-builder" \
      "$BUILD_DIR"; then
      print_error "Failed to build Docker image for $arch"
      exit 1
    fi
    print_success "Built image for $arch"
  done
else
  print_error "Docker buildx is required for multi-platform builds"
  print_info "Install with: docker buildx install"
  exit 1
fi

print_success "Docker image built successfully"
print_info "Starting Ruby builds..."

# Track results
SUCCESSFUL_BUILDS=()
FAILED_BUILDS=()

# Build each combination
TOTAL_BUILDS=$((${#RUBY_VERSIONS[@]} * ${#RAILS_VERSIONS[@]} * ${#ARCHITECTURES[@]}))
CURRENT_BUILD=0

print_info "Total builds to perform: $TOTAL_BUILDS"

for ruby_version in "${RUBY_VERSIONS[@]}"; do
  print_info "Processing Ruby version: $ruby_version"
  for rails_version in "${RAILS_VERSIONS[@]}"; do
    print_info "Processing Rails version: $rails_version"
    for arch in "${ARCHITECTURES[@]}"; do
      print_info "Processing architecture: $arch"
      CURRENT_BUILD=$((CURRENT_BUILD + 1))
      
      echo ""
      print_info "[$CURRENT_BUILD/$TOTAL_BUILDS] Building Ruby $ruby_version + Rails $rails_version for $arch..."
      
      # Check if this combination already exists
      if [[ "$ruby_version" == "edge" ]]; then
        TARBALL_PATTERN="ruby-edge-rails-*-${arch}.tar.gz"
      else
        if [[ "$rails_version" == "edge" ]]; then
          TARBALL_PATTERN="ruby-${ruby_version}-rails-edge-*-${arch}.tar.gz"
        else
          TARBALL_PATTERN="ruby-${ruby_version}-rails-${rails_version}-${arch}.tar.gz"
        fi
      fi
      
      if ls "$OUTPUT_DIR/$arch"/$TARBALL_PATTERN 1>/dev/null 2>&1; then
        print_warning "Skipping: $TARBALL_PATTERN already exists"
        continue
      fi
      
      # Map architecture to Docker platform
      case "$arch" in
        x86_64)
          PLATFORM="linux/amd64"
          ;;
        aarch64)
          PLATFORM="linux/arm64"
          ;;
        *)
          print_error "Unsupported architecture: $arch"
          continue
          ;;
      esac
      
      # Run the build in Docker using the architecture-specific image
      print_info "Running Ruby build in container for $arch..."
      if docker run --rm \
        --platform "$PLATFORM" \
        -e RUBY_VERSION="$ruby_version" \
        -e RAILS_VERSION="$rails_version" \
        -e ARCH="$arch" \
        -v "$OUTPUT_DIR:/output/ruby" \
        -v "$BUILD_DIR/build-ruby.sh:/build/build-ruby.sh:ro" \
        "ruby-builder:$arch"; then
        
        print_success "Successfully built Ruby $ruby_version + Rails $rails_version for $arch"
        SUCCESSFUL_BUILDS+=("ruby-$ruby_version-rails-$rails_version-$arch")
      else
        print_error "Failed to build Ruby $ruby_version + Rails $rails_version for $arch"
        FAILED_BUILDS+=("ruby-$ruby_version-rails-$rails_version-$arch")
      fi
    done
  done
done

# Summary
echo ""
print_header "Build Summary"
print_info "Total builds attempted: $TOTAL_BUILDS"
print_success "Successful: ${#SUCCESSFUL_BUILDS[@]}"
if [[ ${#FAILED_BUILDS[@]} -gt 0 ]]; then
  print_error "Failed: ${#FAILED_BUILDS[@]}"
  echo "Failed builds:"
  for build in "${FAILED_BUILDS[@]}"; do
    echo "  - $build"
  done
  exit 1
else
  print_success "All builds completed successfully!"
fi

# Show output directory contents
echo ""
print_info "Output directory contents:"
for arch in "${ARCHITECTURES[@]}"; do
  echo "  $OUTPUT_DIR/$arch:"
  ls -lh "$OUTPUT_DIR/$arch/" 2>/dev/null | tail -n +2 | head -5 | sed 's/^/    /'
  TOTAL_FILES=$(ls "$OUTPUT_DIR/$arch/" 2>/dev/null | wc -l)
  if [[ $TOTAL_FILES -gt 5 ]]; then
    echo "    ... and $((TOTAL_FILES - 5)) more files"
  fi
done
