#!/bin/bash

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

set -e

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

# Parse command line arguments
DEBUG_BUILD=false
TARGET_PLATFORM=""
ALL_PLATFORMS=false
for arg in "$@"; do
    case "$arg" in
        --debug)
            DEBUG_BUILD=true
            ;;
        --platform=*)
            TARGET_PLATFORM="${arg#*=}"
            ;;
        --all-platforms|--all_platforms|-a)
            ALL_PLATFORMS=true
            ;;
    esac
done

if [ "$ALL_PLATFORMS" = true ] && [ -n "$TARGET_PLATFORM" ]; then
    echo "ERROR: --all-platforms cannot be used together with --platform"
    exit 1
fi

if [ "$ALL_PLATFORMS" = true ]; then
    echo "Building all supported platforms (linux/amd64 + linux/arm64)..."
    echo ""
    DEBUG_FLAG=""
    if [ "$DEBUG_BUILD" = true ]; then
        DEBUG_FLAG="--debug"
    fi

    "$SCRIPT_DIR/build_static.sh" $DEBUG_FLAG --platform=linux/amd64
    "$SCRIPT_DIR/build_static.sh" $DEBUG_FLAG --platform=linux/arm64

    echo ""
    echo "✓ Multi-platform build complete"
    exit 0
fi

if [ "$DEBUG_BUILD" = true ]; then
    echo "=========================================="
    echo "Didactyl MUSL Static Binary Builder (DEBUG MODE)"
    echo "=========================================="
else
    echo "=========================================="
    echo "Didactyl MUSL Static Binary Builder (PRODUCTION MODE)"
    echo "=========================================="
fi
echo "Project directory: $SCRIPT_DIR"
echo "Output directory: $OUTPUT_DIR"
echo "Debug build: $DEBUG_BUILD"
echo ""

# Remove legacy build directory if present
if [ -d "$SCRIPT_DIR/build" ]; then
    rm -rf "$SCRIPT_DIR/build"
    echo "Removed legacy build directory: $SCRIPT_DIR/build"
fi

# 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 (or use explicit target platform override)
if [ -n "$TARGET_PLATFORM" ]; then
    PLATFORM="$TARGET_PLATFORM"
    case "$PLATFORM" in
        linux/amd64)
            OUTPUT_NAME="didactyl_static_x86_64"
            ;;
        linux/arm64)
            OUTPUT_NAME="didactyl_static_arm64"
            ;;
        linux/arm/v7)
            OUTPUT_NAME="didactyl_static_armv7"
            ;;
        linux/arm/v6)
            OUTPUT_NAME="didactyl_static_armv6"
            ;;
        *)
            OUTPUT_NAME="didactyl_static_custom"
            ;;
    esac
else
    ARCH=$(uname -m)
    case "$ARCH" in
        x86_64)
            PLATFORM="linux/amd64"
            OUTPUT_NAME="didactyl_static_x86_64"
            ;;
        aarch64|arm64)
            PLATFORM="linux/arm64"
            OUTPUT_NAME="didactyl_static_arm64"
            ;;
        *)
            echo "WARNING: Unknown architecture: $ARCH"
            echo "Defaulting to linux/amd64"
            PLATFORM="linux/amd64"
            OUTPUT_NAME="didactyl_static_${ARCH}"
            ;;
    esac
fi

# Append _debug suffix to output name for debug builds
if [ "$DEBUG_BUILD" = true ]; then
    OUTPUT_NAME="${OUTPUT_NAME}_debug"
fi

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

# Verify Docker can execute the requested target platform (QEMU/binfmt for cross-arch)
HOST_ARCH=$(uname -m)
case "$HOST_ARCH" in
    x86_64) HOST_PLATFORM="linux/amd64" ;;
    aarch64|arm64) HOST_PLATFORM="linux/arm64" ;;
    armv7l) HOST_PLATFORM="linux/arm/v7" ;;
    armv6l) HOST_PLATFORM="linux/arm/v6" ;;
    *) HOST_PLATFORM="unknown" ;;
esac

if [ "$HOST_PLATFORM" != "$PLATFORM" ]; then
    echo "Cross-architecture build detected: host=$HOST_PLATFORM target=$PLATFORM"
    echo "Checking Docker emulation support for $PLATFORM..."
    if ! $DOCKER_CMD run --rm --platform "$PLATFORM" alpine:3.19 uname -m > /dev/null 2>&1; then
        echo ""
        echo "ERROR: Docker cannot execute $PLATFORM containers on this host"
        echo "This usually means QEMU/binfmt is not configured."
        echo "Run this once, then retry:"
        echo "  docker run --rm --privileged multiarch/qemu-user-static --reset -p yes"
        echo "Optional verify command:"
        echo "  docker run --rm --platform $PLATFORM alpine:3.19 uname -m"
        echo ""
        exit 1
    fi
    echo "✓ Docker emulation for $PLATFORM is available"
    echo ""
fi

# Check if Alpine base image is cached
echo "Checking for cached Alpine Docker image..."
if ! docker images alpine:3.19 --format "{{.Repository}}:{{.Tag}}" | grep -q "alpine:3.19"; then
    echo "⚠ Alpine 3.19 image not found in cache"
    echo "Attempting to pull Alpine 3.19 image..."
    if ! docker pull alpine:3.19; then
        echo ""
        echo "ERROR: Failed to pull Alpine 3.19 image"
        echo "This is required for the static build."
        echo ""
        exit 1
    fi
    echo "✓ Alpine 3.19 image pulled successfully"
else
    echo "✓ Alpine 3.19 image found in cache"
fi
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 didactyl with full static linking"
echo ""

$DOCKER_CMD build \
    --network host \
    --platform "$PLATFORM" \
    --build-arg DEBUG_BUILD=$DEBUG_BUILD \
    -f "$DOCKERFILE" \
    -t didactyl-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 "=========================================="

# Reuse the already-built final image and extract binary directly
# (avoids a second docker build pass)
CONTAINER_ID=$($DOCKER_CMD create didactyl-musl-builder:latest /didactyl_static)

# Copy binary from final image
$DOCKER_CMD cp "$CONTAINER_ID:/didactyl_static" "$OUTPUT_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: $OUTPUT_DIR/$OUTPUT_NAME"
echo ""

# Make binary executable
chmod +x "$OUTPUT_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 "$OUTPUT_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 "$OUTPUT_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 "=========================================="
echo "Build Summary"
echo "=========================================="
echo "Binary: $OUTPUT_DIR/$OUTPUT_NAME"
echo "Size: $(du -h "$OUTPUT_DIR/$OUTPUT_NAME" | cut -f1)"
echo "Static: $TRULY_STATIC"
echo "Debug: $DEBUG_BUILD"
echo "Platform: $PLATFORM"
echo "=========================================="
