#!/bin/bash

# S3 File Watcher Build Script
# Compiles for macOS (ARM/Intel), Windows (amd64), and Linux (amd64)

set -e

# ═══════════════════════════════════════════════════════════════════════════════
# Configuration
# ═══════════════════════════════════════════════════════════════════════════════

BINARY_NAME="s3-file-watcher"
SOURCE_FILE="s3-file-watcher.go"

# Get script directory and set up paths
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
CODE_DIR="$PROJECT_DIR/code"
BIN_DIR="$PROJECT_DIR/bin"

# Build flags for smaller binaries
LDFLAGS="-s -w"

# ═══════════════════════════════════════════════════════════════════════════════
# Helper Functions
# ═══════════════════════════════════════════════════════════════════════════════

print_banner() {
    echo ""
    echo "╔══════════════════════════════════════════════════════════════╗"
    echo "║   📦  S3 File Watcher - Build Script                         ║"
    echo "╚══════════════════════════════════════════════════════════════╝"
    echo ""
}

print_usage() {
    echo "Usage: $0 [OPTIONS]"
    echo ""
    echo "Options:"
    echo "  --all           Build for all platforms (default if no target specified)"
    echo "  --current       Build for current platform only (auto-detected)"
    echo "  --linux         Build for Linux (amd64)"
    echo "  --darwin        Build for macOS (Intel and Apple Silicon)"
    echo "  --darwin-amd64  Build for macOS Intel only"
    echo "  --darwin-arm64  Build for macOS Apple Silicon only"
    echo "  --windows       Build for Windows (amd64)"
    echo "  --clean         Remove all binaries before building"
    echo "  --help, -h      Show this help message"
    echo ""
    echo "Examples:"
    echo "  $0                    # Build for all platforms"
    echo "  $0 --current          # Build for current platform only"
    echo "  $0 --darwin --linux   # Build for macOS and Linux"
    echo "  $0 --clean --all      # Clean and rebuild all"
    echo ""
}

detect_platform() {
    local os=$(uname -s | tr '[:upper:]' '[:lower:]')
    local arch=$(uname -m)
    
    case "$os" in
        darwin) CURRENT_OS="darwin" ;;
        linux)  CURRENT_OS="linux" ;;
        mingw*|msys*|cygwin*) CURRENT_OS="windows" ;;
        *) CURRENT_OS="unknown" ;;
    esac
    
    case "$arch" in
        x86_64|amd64) CURRENT_ARCH="amd64" ;;
        arm64|aarch64) CURRENT_ARCH="arm64" ;;
        *) CURRENT_ARCH="unknown" ;;
    esac
}

check_go() {
    if ! command -v go &> /dev/null; then
        echo "❌ Go is not installed. Please install Go 1.21+ first."
        echo "   https://golang.org/dl/"
        exit 1
    fi
    echo "Go version: $(go version)"
}

setup_module() {
    cd "$CODE_DIR"
    
    if [ ! -f "go.mod" ]; then
        echo "📦 Initializing Go module..."
        go mod init github.com/theorchard/collab/s3-file-watcher
    fi
    
    echo "📥 Downloading dependencies..."
    go mod tidy
}

build_binary() {
    local goos=$1
    local goarch=$2
    local suffix=$3
    
    local output_name="${BINARY_NAME}${suffix}"
    if [ "$goos" = "windows" ]; then
        output_name="${output_name}.exe"
    fi
    
    echo -n "  Building ${output_name}... "
    
    GOOS=$goos GOARCH=$goarch go build -ldflags="$LDFLAGS" -o "$BIN_DIR/$output_name" "$SOURCE_FILE"
    
    local size=$(du -h "$BIN_DIR/$output_name" | cut -f1)
    echo "✅ ($size)"
}

clean_binaries() {
    echo "🧹 Cleaning existing binaries..."
    rm -rf "$BIN_DIR"
    mkdir -p "$BIN_DIR"
}

# ═══════════════════════════════════════════════════════════════════════════════
# Build Targets
# ═══════════════════════════════════════════════════════════════════════════════

build_current() {
    detect_platform
    echo ""
    echo "🔨 Building for current platform ($CURRENT_OS/$CURRENT_ARCH)..."
    echo ""
    
    if [ "$CURRENT_OS" = "unknown" ] || [ "$CURRENT_ARCH" = "unknown" ]; then
        echo "❌ Could not detect current platform"
        exit 1
    fi
    
    build_binary "$CURRENT_OS" "$CURRENT_ARCH" ""
}

build_linux() {
    echo ""
    echo "🐧 Building for Linux..."
    echo ""
    build_binary "linux" "amd64" "-linux-amd64"
}

build_darwin_amd64() {
    build_binary "darwin" "amd64" "-darwin-amd64"
}

build_darwin_arm64() {
    build_binary "darwin" "arm64" "-darwin-arm64"
}

build_darwin() {
    echo ""
    echo "🍎 Building for macOS..."
    echo ""
    build_darwin_amd64
    build_darwin_arm64
}

build_windows() {
    echo ""
    echo "🪟 Building for Windows..."
    echo ""
    build_binary "windows" "amd64" "-windows-amd64"
}

build_all() {
    echo ""
    echo "🔨 Building for all platforms..."
    
    # Current platform first (no suffix for convenience)
    detect_platform
    if [ "$CURRENT_OS" != "unknown" ] && [ "$CURRENT_ARCH" != "unknown" ]; then
        echo ""
        echo "📍 Current platform ($CURRENT_OS/$CURRENT_ARCH)..."
        echo ""
        build_binary "$CURRENT_OS" "$CURRENT_ARCH" ""
    fi
    
    build_linux
    build_darwin
    build_windows
}

print_summary() {
    echo ""
    echo "════════════════════════════════════════════════════════════════"
    echo "  ✅ Build complete!"
    echo ""
    echo "  Binaries created in $BIN_DIR:"
    echo ""
    ls -lh "$BIN_DIR"/${BINARY_NAME}* 2>/dev/null | awk '{print "    " $NF " (" $5 ")"}'
    echo ""
    echo "  Usage:"
    echo "    ./bin/${BINARY_NAME} --help"
    echo "    ./bin/${BINARY_NAME} --config config.json"
    echo "    ./bin/${BINARY_NAME} --watch-dir /path --s3-bucket bucket --patterns '*.json'"
    echo "════════════════════════════════════════════════════════════════"
    echo ""
}

# ═══════════════════════════════════════════════════════════════════════════════
# Main
# ═══════════════════════════════════════════════════════════════════════════════

main() {
    print_banner
    
    # Parse arguments
    DO_CLEAN=false
    BUILD_TARGETS=()
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --help|-h)
                print_usage
                exit 0
                ;;
            --clean)
                DO_CLEAN=true
                shift
                ;;
            --all)
                BUILD_TARGETS+=("all")
                shift
                ;;
            --current)
                BUILD_TARGETS+=("current")
                shift
                ;;
            --linux)
                BUILD_TARGETS+=("linux")
                shift
                ;;
            --darwin)
                BUILD_TARGETS+=("darwin")
                shift
                ;;
            --darwin-amd64)
                BUILD_TARGETS+=("darwin-amd64")
                shift
                ;;
            --darwin-arm64)
                BUILD_TARGETS+=("darwin-arm64")
                shift
                ;;
            --windows)
                BUILD_TARGETS+=("windows")
                shift
                ;;
            *)
                echo "Unknown option: $1"
                print_usage
                exit 1
                ;;
        esac
    done
    
    # Default to --all if no targets specified
    if [ ${#BUILD_TARGETS[@]} -eq 0 ]; then
        BUILD_TARGETS+=("all")
    fi
    
    # Check prerequisites
    check_go
    
    # Setup
    mkdir -p "$BIN_DIR"
    
    if [ "$DO_CLEAN" = true ]; then
        clean_binaries
    fi
    
    # Setup Go module
    setup_module
    
    # Execute build targets
    for target in "${BUILD_TARGETS[@]}"; do
        case $target in
            all)           build_all ;;
            current)       build_current ;;
            linux)         build_linux ;;
            darwin)        build_darwin ;;
            darwin-amd64)  build_darwin_amd64 ;;
            darwin-arm64)  build_darwin_arm64 ;;
            windows)       build_windows ;;
        esac
    done
    
    print_summary
}

main "$@"
