#!/bin/bash
set -e

OPENSSL_VERSION=3.5.0

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
BUILD_DIR="${SCRIPT_DIR}/build"
MUSL_CROSS_DIR="$HOME/.musl-cross"
mkdir -p "$BUILD_DIR"

# Helper: compare versions (returns 0 if $1 >= $2)
version_ge() {
    [ "$1" = "$2" ] && return 0
    [ "$(printf '%s\n' "$1" "$2" | sort -V | head -n1)" = "$2" ]
}

# Find all installed musl cross toolchains
TOOLCHAINS=()
for tc in "$MUSL_CROSS_DIR"/*-linux-musl-cross; do
    [ -d "$tc" ] || continue
    arch=$(basename "$tc" | sed 's/-linux-musl-cross//')
    TOOLCHAINS+=("$arch")
done

if [ ${#TOOLCHAINS[@]} -eq 0 ]; then
    echo "No musl cross toolchains found in $MUSL_CROSS_DIR. Exiting."
    exit 1
fi

echo "Found musl cross toolchains: ${TOOLCHAINS[*]}"

for ARCH in "${TOOLCHAINS[@]}"; do
    echo "==============================="
    echo "Checking OpenSSL for $ARCH..."
    echo "==============================="
    if [ "$ARCH" = "x86_64" ]; then
        MUSL_PREFIX="$MUSL_CROSS_DIR/x86_64-linux-musl-cross"
        OPENSSL_TARGET=linux-x86_64
    elif [ "$ARCH" = "aarch64" ]; then
        MUSL_PREFIX="$MUSL_CROSS_DIR/aarch64-linux-musl-cross"
        OPENSSL_TARGET=linux-aarch64
    else
        # Try to guess OpenSSL target for other musl toolchains
        OPENSSL_TARGET="linux-$ARCH"
        MUSL_PREFIX="$MUSL_CROSS_DIR/${ARCH}-linux-musl-cross"
    fi
    SYSROOT="$MUSL_PREFIX/${ARCH}-linux-musl/sysroot"
    CC="$MUSL_PREFIX/bin/${ARCH}-linux-musl-gcc"
    AR="$MUSL_PREFIX/bin/${ARCH}-linux-musl-ar"
    RANLIB="$MUSL_PREFIX/bin/${ARCH}-linux-musl-ranlib"

    SKIP_BUILD=0
    if [ -f "$SYSROOT/usr/lib/libssl.a" ]; then
        # Try to extract version from opensslv.h
        OPENSSLV_H="$SYSROOT/usr/include/openssl/opensslv.h"
        if [ -f "$OPENSSLV_H" ]; then
            INSTALLED_VERSION=$(grep '# *define *OPENSSL_VERSION_TEXT' "$OPENSSLV_H" | sed -E 's/.*OpenSSL ([0-9.]+)[^ ]*.*/\1/')
            if [ -n "$INSTALLED_VERSION" ]; then
                echo "Found installed OpenSSL version: $INSTALLED_VERSION"
                if version_ge "$INSTALLED_VERSION" "$OPENSSL_VERSION"; then
                    echo "OpenSSL $INSTALLED_VERSION is up-to-date (>= $OPENSSL_VERSION), skipping build for $ARCH."
                    SKIP_BUILD=1
                else
                    echo "OpenSSL $INSTALLED_VERSION is older than $OPENSSL_VERSION, will rebuild."
                fi
            else
                echo "Could not determine installed OpenSSL version, will rebuild."
            fi
        else
            echo "No opensslv.h found, will rebuild."
        fi
    fi

    if [ "$SKIP_BUILD" -eq 1 ]; then
        echo
        continue
    fi

    cd "$BUILD_DIR"
    if [ ! -d "openssl-${OPENSSL_VERSION}" ]; then
        if [ ! -f "openssl-${OPENSSL_VERSION}.tar.gz" ]; then
            wget "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz"
        fi
        tar xf "openssl-${OPENSSL_VERSION}.tar.gz"
    fi
    cd "openssl-${OPENSSL_VERSION}"

    # Clean previous build for this arch
    make clean || true

    echo "Configuring for $ARCH with sysroot $SYSROOT..."
    CC="$CC" AR="$AR" RANLIB="$RANLIB" ./Configure "$OPENSSL_TARGET" no-shared --prefix="$SYSROOT/usr"
    echo "Building..."
    make -j"$(nproc)"
    echo "Installing to $SYSROOT/usr ..."
    make install_sw
    cd "$BUILD_DIR"
    echo "Done for $ARCH."
    echo
    # Remove build dir for next arch to avoid cross contamination
    rm -rf "openssl-${OPENSSL_VERSION}"
    tar xf "openssl-${OPENSSL_VERSION}.tar.gz"
done

echo "OpenSSL built and installed for all detected musl toolchains."