#!/bin/bash

# Build fully static MUSL binaries for Ginxsom using Alpine Docker
# Produces truly portable binaries with zero runtime dependencies

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUILD_DIR="$SCRIPT_DIR/build"
DOCKERFILE="$SCRIPT_DIR/Dockerfile.alpine-musl"

# Parse command line arguments
DEBUG_BUILD=false
if [[ "$1" == "--debug" ]]; then
    DEBUG_BUILD=true
    echo "=========================================="
    echo "Ginxsom MUSL Static Binary Builder (DEBUG MODE)"
    echo "=========================================="
else
    echo "=========================================="
    echo "Ginxsom MUSL Static Binary Builder (PRODUCTION MODE)"
    echo "=========================================="
fi
echo "Project directory: $SCRIPT_DIR"
echo "Build directory: $BUILD_DIR"
echo "Debug build: $DEBUG_BUILD"
echo ""

# Create build directory
mkdir -p "$BUILD_DIR"

# Check if Docker is available
if ! command -v docker &> /dev/null; then
    echo "ERROR: Docker is not installed or not in PATH"
    echo ""
    echo "Docker is required to build MUSL static binaries."
    echo "Please install Docker:"
    echo "  - Ubuntu/Debian: sudo apt install docker.io"
    echo "  - Or visit: https://docs.docker.com/engine/install/"
    echo ""
    exit 1
fi

# Check if Docker daemon is running
if ! docker info &> /dev/null; then
    echo "ERROR: Docker daemon is not running or user not in docker group"
    echo ""
    echo "Please start Docker and ensure you're in the docker group:"
    echo "  - sudo systemctl start docker"
    echo "  - sudo usermod -aG docker $USER && newgrp docker"
    echo "  - Or start Docker Desktop"
    echo ""
    exit 1
fi

DOCKER_CMD="docker"

echo "✓ Docker is available and running"
echo ""

# Detect architecture
ARCH=$(uname -m)
case "$ARCH" in
    x86_64)
        PLATFORM="linux/amd64"
        OUTPUT_NAME="ginxsom-fcgi_static_x86_64"
        ;;
    aarch64|arm64)
        PLATFORM="linux/arm64"
        OUTPUT_NAME="ginxsom-fcgi_static_arm64"
        ;;
    *)
        echo "WARNING: Unknown architecture: $ARCH"
        echo "Defaulting to linux/amd64"
        PLATFORM="linux/amd64"
        OUTPUT_NAME="ginxsom-fcgi_static_${ARCH}"
        ;;
esac

echo "Building for platform: $PLATFORM"
echo "Output binary: $OUTPUT_NAME"
echo ""

# Build the Docker image
echo "=========================================="
echo "Step 1: Building Alpine Docker image"
echo "=========================================="
echo "This will:"
echo "  - Use Alpine Linux (native MUSL)"
echo "  - Build all dependencies statically"
echo "  - Compile Ginxsom with full static linking"
echo ""

$DOCKER_CMD build \
    --platform "$PLATFORM" \
    --build-arg DEBUG_BUILD=$DEBUG_BUILD \
    -f "$DOCKERFILE" \
    -t ginxsom-musl-builder:latest \
    --progress=plain \
    . || {
        echo ""
        echo "ERROR: Docker build failed"
        echo "Check the output above for details"
        exit 1
    }

echo ""
echo "✓ Docker image built successfully"
echo ""

# Extract the binary from the container
echo "=========================================="
echo "Step 2: Extracting static binary"
echo "=========================================="

# Build the builder stage to extract the binary
$DOCKER_CMD build \
    --platform "$PLATFORM" \
    --build-arg DEBUG_BUILD=$DEBUG_BUILD \
    --target builder \
    -f "$DOCKERFILE" \
    -t ginxsom-static-builder-stage:latest \
    . > /dev/null 2>&1

# Create a temporary container to copy the binary
CONTAINER_ID=$($DOCKER_CMD create ginxsom-static-builder-stage:latest)

# Copy binary from container
$DOCKER_CMD cp "$CONTAINER_ID:/build/ginxsom-fcgi_static" "$BUILD_DIR/$OUTPUT_NAME" || {
    echo "ERROR: Failed to extract binary from container"
    $DOCKER_CMD rm "$CONTAINER_ID" 2>/dev/null
    exit 1
}

# Clean up container
$DOCKER_CMD rm "$CONTAINER_ID" > /dev/null

echo "✓ Binary extracted to: $BUILD_DIR/$OUTPUT_NAME"
echo ""

# Make binary executable
chmod +x "$BUILD_DIR/$OUTPUT_NAME"

# Verify the binary
echo "=========================================="
echo "Step 3: Verifying static binary"
echo "=========================================="
echo ""

echo "Checking for dynamic dependencies:"
if LDD_OUTPUT=$(timeout 5 ldd "$BUILD_DIR/$OUTPUT_NAME" 2>&1); then
    if echo "$LDD_OUTPUT" | grep -q "not a dynamic executable"; then
        echo "✓ Binary is fully static (no dynamic dependencies)"
        TRULY_STATIC=true
    elif echo "$LDD_OUTPUT" | grep -q "statically linked"; then
        echo "✓ Binary is statically linked"
        TRULY_STATIC=true
    else
        echo "⚠ WARNING: Binary may have dynamic dependencies:"
        echo "$LDD_OUTPUT"
        TRULY_STATIC=false
    fi
else
    # ldd failed or timed out - check with file command instead
    if file "$BUILD_DIR/$OUTPUT_NAME" | grep -q "statically linked"; then
        echo "✓ Binary is statically linked (verified with file command)"
        TRULY_STATIC=true
    else
        echo "⚠ Could not verify static linking (ldd check failed)"
        TRULY_STATIC=false
    fi
fi
echo ""

echo "File size: $(ls -lh "$BUILD_DIR/$OUTPUT_NAME" | awk '{print $5}')"
echo ""

# Summary
echo "=========================================="
echo "Build Summary"
echo "=========================================="
echo "Binary: $BUILD_DIR/$OUTPUT_NAME"
echo "Size: $(du -h "$BUILD_DIR/$OUTPUT_NAME" | cut -f1)"
echo "Platform: $PLATFORM"
if [ "$DEBUG_BUILD" = true ]; then
    echo "Build Type: DEBUG (with symbols, no optimization)"
else
    echo "Build Type: PRODUCTION (optimized, stripped)"
fi
if [ "$TRULY_STATIC" = true ]; then
    echo "Linkage: Fully static binary (Alpine MUSL-based)"
    echo "Portability: Works on ANY Linux distribution"
else
    echo "Linkage: Static binary (may have minimal dependencies)"
fi
echo ""
echo "✓ Build complete!"
echo ""

# Clean up old dynamic build artifacts
echo "=========================================="
echo "Cleaning up old build artifacts"
echo "=========================================="
echo ""
if ls build/*.o 2>/dev/null | grep -q .; then
    echo "Removing old .o files from dynamic builds..."
    rm -f build/*.o
    echo "✓ Cleanup complete"
else
    echo "No .o files to clean"
fi

# Also remove old dynamic binary if it exists
if [ -f "build/ginxsom-fcgi" ]; then
    echo "Removing old dynamic binary..."
    rm -f build/ginxsom-fcgi
    echo "✓ Old binary removed"
fi

echo ""
echo "Deployment:"
echo "  scp $BUILD_DIR/$OUTPUT_NAME user@server:/path/to/ginxsom/"
echo ""