#!/bin/sh

AUTOMERGE_FOUND=0
PKG_CFLAGS=""
PKG_LIBS=""

# Find compiler and export flags
CC=`"${R_HOME}/bin/R" CMD config CC`
CFLAGS=`"${R_HOME}/bin/R" CMD config CFLAGS`
LDFLAGS=`"${R_HOME}/bin/R" CMD config LDFLAGS`
export CC CFLAGS LDFLAGS

# Helper function: detect cmake
detect_cmake() {
  if command -v cmake >/dev/null 2>&1; then
    return 0
  fi
  export PATH=$PATH:/Applications/CMake.app/Contents/bin
  if command -v cmake >/dev/null 2>&1; then
    return 0
  fi
  echo "ERROR: CMake not found"
  exit 1
}

# Helper function: check for UTF-32 indexing in system library
check_utf32_indexing() {
    echo "#include <automerge-c/config.h>
    #ifndef AUTOMERGE_C_UTF32
    #error \"UTF-32 indexing is not enabled\"
    #endif
    int main(void) { return 0; }" | \
        ${CC} -I"$1" -xc - -c -o /dev/null 2>/dev/null
}

if [ "${AUTOMERGE_LIBS}" = "1" ]; then
    echo "AUTOMERGE_LIBS=1: forcing bundled source compilation"
else
    echo "Checking for system automerge installation..."

    for prefix in /usr/local /usr /opt/local /opt/homebrew; do
        if [ -f "${prefix}/include/automerge-c/automerge.h" ] && \
           [ -f "${prefix}/lib/libautomerge.a" ]; then
            echo "Found automerge in ${prefix}"

            # Check if it's built with UTF-32 indexing via compilation test
            if check_utf32_indexing "${prefix}/include"; then
                echo "Verified UTF-32 character indexing enabled"
                PKG_CFLAGS="-I${prefix}/include"
                PKG_LIBS="-L${prefix}/lib -lautomerge"
                AUTOMERGE_FOUND=1
                break
            else
                echo "Detected system automerge uses UTF-8 byte indexing"
                echo "This package requires UTF-32 character indexing for natural R semantics"
                echo "Will build from bundled source instead"
            fi
        fi
    done

    if [ ${AUTOMERGE_FOUND} -eq 0 ] && command -v pkg-config >/dev/null 2>&1; then
        if pkg-config --exists automerge-c 2>/dev/null; then
            echo "Found automerge via pkg-config"

            # Try to get the prefix from pkg-config
            prefix=$(pkg-config --variable=prefix automerge-c 2>/dev/null)
            if [ -n "${prefix}" ]; then
                if check_utf32_indexing "${prefix}/include"; then
                    echo "Verified UTF-32 character indexing enabled"
                    PKG_CFLAGS=$(pkg-config --cflags automerge-c)
                    PKG_LIBS=$(pkg-config --libs automerge-c)
                    AUTOMERGE_FOUND=1
                else
                    echo "Detected system automerge uses UTF-8 byte indexing"
                    echo "This package requires UTF-32 character indexing for natural R semantics"
                    echo "Will build from bundled source instead"
                fi
            fi
        fi
    fi
fi

if [ ${AUTOMERGE_FOUND} -eq 0 ]; then
    echo "System automerge not found, building from bundled source..."

    # Minimum Rust version required (MSRV)
    RUST_MSRV="1.84"

    # Check for Rust toolchain (cargo and rustc)
    # CRAN policy: check both system PATH and ~/.cargo/bin
    CARGO_CMD=""
    RUSTC_CMD=""

    # First check PATH
    if command -v cargo >/dev/null 2>&1; then
        CARGO_CMD="cargo"
    fi
    if command -v rustc >/dev/null 2>&1; then
        RUSTC_CMD="rustc"
    fi

    # Also check ~/.cargo/bin (rustup default location, often not on PATH)
    if [ -z "$CARGO_CMD" ] && [ -x "$HOME/.cargo/bin/cargo" ]; then
        CARGO_CMD="$HOME/.cargo/bin/cargo"
        export PATH="$HOME/.cargo/bin:$PATH"
    fi
    if [ -z "$RUSTC_CMD" ] && [ -x "$HOME/.cargo/bin/rustc" ]; then
        RUSTC_CMD="$HOME/.cargo/bin/rustc"
    fi

    # Verify both cargo and rustc are found
    if [ -z "$CARGO_CMD" ] || [ -z "$RUSTC_CMD" ]; then
        echo "-------------------- RUST TOOLCHAIN NOT FOUND --------------------"
        echo "This package requires Rust >= $RUST_MSRV to build from source."
        echo ""
        echo "Install Rust via your system package manager:"
        echo "  - Fedora/RHEL:   dnf install cargo"
        echo "  - Debian/Ubuntu: apt-get install cargo rustc"
        echo "  - macOS:         brew install rust"
        echo ""
        echo "Or install via rustup (recommended): https://rustup.rs/"
        echo ""
        echo "Alternatively, install automerge-c system-wide to skip Rust build."
        echo "------------------------------------------------------------------"
        exit 1
    fi

    # Check Rust version meets minimum requirement
    RUST_VERSION=$($RUSTC_CMD --version | sed -n 's/rustc \([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p')
    RUST_MAJOR=$(echo $RUST_VERSION | cut -d. -f1)
    RUST_MINOR=$(echo $RUST_VERSION | cut -d. -f2)
    MSRV_MAJOR=$(echo $RUST_MSRV | cut -d. -f1)
    MSRV_MINOR=$(echo $RUST_MSRV | cut -d. -f2)

    if [ "$RUST_MAJOR" -lt "$MSRV_MAJOR" ] || \
       { [ "$RUST_MAJOR" -eq "$MSRV_MAJOR" ] && [ "$RUST_MINOR" -lt "$MSRV_MINOR" ]; }; then
        echo "-------------------- RUST VERSION TOO OLD --------------------"
        echo "Found Rust $RUST_VERSION but this package requires Rust >= $RUST_MSRV"
        echo ""
        echo "Update Rust via your package manager or rustup:"
        echo "  - Fedora/RHEL:   dnf update cargo"
        echo "  - Debian/Ubuntu: apt-get update && apt-get upgrade cargo rustc"
        echo "  - macOS:         brew upgrade rust"
        echo "  - rustup:        rustup update stable"
        echo "---------------------------------------------------------------"
        exit 1
    fi

    detect_cmake

    echo "Building automerge-c..."
    echo "using Rust package manager: '$($CARGO_CMD --version)'"
    echo "using Rust compiler: '$($RUSTC_CMD --version)'"

    rm -rf am-build am-install

    # Set TMPDIR to avoid rustix test file warning in R CMD check
    export TMPDIR="${PWD}/am-build/tmp"
    mkdir -p "$TMPDIR"

    # Set CARGO_HOME to prevent writes to ~/.cargo (CRAN policy)
    export CARGO_HOME="${PWD}/am-build/.cargo"
    mkdir -p "$CARGO_HOME"

    # Generate vendor config with absolute path (env vars don't work for source replacement)
    cat > "$CARGO_HOME/config.toml" << EOF
[source.crates-io]
replace-with = "vendored-sources"

[source.vendored-sources]
directory = "${PWD}/src/automerge/rust/vendor"
EOF

    # Extract vendored Rust dependencies (CMakeLists.txt configures Cargo to use them)
    if [ -f "src/automerge/rust/vendor.tar.xz" ] && [ ! -d "src/automerge/rust/vendor" ]; then
        echo "Extracting vendored Rust dependencies..."
        xz -dc src/automerge/rust/vendor.tar.xz | tar -xf - -C src/automerge/rust
    fi

    cmake -S src/automerge/rust/automerge-c -B am-build \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
        -DCMAKE_INSTALL_PREFIX="${PWD}/am-install" \
        -DCMAKE_INSTALL_LIBDIR=lib \
        -DBUILD_TESTING=OFF \
        -DCMAKE_COLOR_MAKEFILE=OFF \
        -DCMAKE_INSTALL_MESSAGE=NEVER \
        -DUTF32_INDEXING=ON \
        || { echo "ERROR: CMake configuration failed"; exit 1; }

    echo "Building (this may take several minutes)..."
    cmake --build am-build --config Release \
        || { echo "ERROR: Build failed"; exit 1; }

    cmake --build am-build --target install \
        || { echo "ERROR: Install failed"; exit 1; }

    rm -rf am-build

    if [ ! -d "am-install/lib" ]; then
        echo "ERROR: Installation did not create expected lib directory"
        exit 1
    fi

    echo "Successfully built automerge-c from source"

    PKG_CFLAGS="-I../am-install/include"
    PKG_LIBS="../am-install/lib/libautomerge.a -pthread"
fi

case "$(uname -s)" in
    Darwin*)
        PKG_LIBS="${PKG_LIBS} -framework Security -framework Foundation"
        ;;
    Linux*)
        PKG_LIBS="${PKG_LIBS} -ldl -lm -lrt"
        ;;
esac

echo "Configuration:"
echo "  PKG_CFLAGS: ${PKG_CFLAGS}"
echo "  PKG_LIBS: ${PKG_LIBS}"

sed -e "s|@PKG_CFLAGS@|${PKG_CFLAGS}|" \
    -e "s|@PKG_LIBS@|${PKG_LIBS}|" \
    src/Makevars.in > src/Makevars

exit 0
