#!/bin/bash

# Exit on error
set -euo pipefail

# DIRECTORIES
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
EXE_DIR="${SCRIPT_DIR}/output"
PROJECTNAME="simple_object_storage"
JOBS=${JOBS:-$(nproc)}

# FUNCTIONS
function title() {
    echo "----------------------------------------"
    # Center the text
    local text="$1"
    local line_length=40
    local text_length=${#text}
    local padding=$(( (line_length - text_length) / 2 ))
    printf "%*s%s%*s\n" $padding "" "$text" $padding ""
    echo "----------------------------------------"
}   

function die() {
    echo " "
    title "$1"
    echo " "
    exit 1
}

function build_for_arch() {
    # Arguments: <arch> <musl_path> <c_compiler> <cxx_compiler> <exe_linker_flags> <cxx_flags> <cmake_system_processor>
    local arch="$1"
    local musl_path="$2"
    local c_compiler="$3"
    local cxx_compiler="$4"
    local exe_linker_flags="$5"
    local cxx_flags="$6"
    local cmake_system_processor="$7"

    echo "Building for $arch (musl)..."

    local build_dir="build_${arch}"
    local cmake_args=(
        -B "$build_dir"
        -DCMAKE_BUILD_TYPE=Release
        "-DCMAKE_C_COMPILER=$musl_path/bin/$c_compiler"
        "-DCMAKE_CXX_COMPILER=$musl_path/bin/$cxx_compiler"
        -DCMAKE_EXE_LINKER_FLAGS="$exe_linker_flags"
        -DCMAKE_CXX_FLAGS="$cxx_flags"
        .
    )
    if [[ -n "$cmake_system_processor" ]]; then
        cmake_args+=("-DCMAKE_SYSTEM_PROCESSOR=$cmake_system_processor")
    fi

    cmake "${cmake_args[@]}"
    cmake --build "$build_dir" --target simple_object_storage --config Release -j"$JOBS"
    mkdir -p "${EXE_DIR}"
    cp "$build_dir/${PROJECTNAME}" "${EXE_DIR}/${PROJECTNAME}.$arch"

    echo "$arch executable built: ${PROJECTNAME}.$arch"
}

function build_amd64() {
    build_for_arch \
        "amd64" \
        "$HOME/.musl-cross/x86_64-linux-musl-cross" \
        "x86_64-linux-musl-gcc" \
        "x86_64-linux-musl-g++" \
        "-static" \
        "-march=x86-64" \
        ""
}

function build_arm64() {
    build_for_arch \
        "arm64" \
        "$HOME/.musl-cross/aarch64-linux-musl-cross" \
        "aarch64-linux-musl-gcc" \
        "aarch64-linux-musl-g++" \
        "-static" \
        "-march=armv8-a" \
        "aarch64"
}

#--------------------------------
# MAIN
#--------------------------------

OLD_DIR=$(pwd)
cd "$SCRIPT_DIR"


mkdir -p "${EXE_DIR}"

BUILDSTR="${1:-amd64}"

if [ "$BUILDSTR" = "all" ] || [ "$BUILDSTR" = "arm64" ]; then
    build_arm64 || die "Failed to build linux-arm64 executable"
fi

if [ "$BUILDSTR" = "all" ] || [ "$BUILDSTR" = "amd64" ]; then
    build_amd64 || die "Failed to build linux-x86_64 executable"
fi

echo "Build completed successfully!"

cd "$OLD_DIR"