#!/usr/bin/env bash

# Debian dependencies: libssl-dev

# Debian dependencies for 32-bit: gcc-multilib libssl-dev:i386
# 32-bit build requires: rustup target add i586-unknown-linux-gnu

# Requires an IceCat binary, which in turn requires Guix.
# See https://guix.gnu.org/manual/en/html_node/Installation.html
# guix install icecat; guix pack -S /opt/gnu/bin=bin -RR icecat
# FIXME: On Windows/Mac, it should probably use the system browser instead of IceCat; alternatively the whole thing could be stuffed into WSL2 though that is a little less obvious for users.

# uftrace, not required but useful for debugging:
# sudo apt install pandoc libdw-dev python3-dev libncursesw5-dev pkg-config libluajit-5.1-dev libcapstone-dev libtraceevent-dev
# https://github.com/namhyung/uftrace
# Seems like it needs rustup default nightly
# and then building something like:
# RUSTFLAGS="-Z instrument-mcount -C passes=ee-instrument<post-inline>" cargo build --features debug --bins
# then ~/uftrace/uftrace  '~/hc/ctoolbox/target/debug/ctoolbox'
# but that doesn't seem to work properly for me

# Tests in unix.rs assume `sleep` command is available.

set -euo pipefail

pushd ctoolbox || exit 1
cargo doc --offline --no-deps --document-private-items
popd || exit 1

if [[ "${1-}" == "--debug" ]]; then
    release="debug"
    shift
else
    release="release"
    if [[ "${1-}" == "--release" ]]; then
        shift
    fi
fi

platform="${1-}"

platforms=("linux-x64" "linux-x86")

if [[ "$platform" != "all" ]]; then
    platforms=("$platform")
fi

for p in "${platforms[@]}"; do
    if [[ "$p" == "linux-x64" ]]; then
        target=x86_64-unknown-linux-gnu
    elif [[ "$p" == "linux-x86" ]]; then
        target="i586-unknown-linux-gnu"
    else
        echo "Unknown or unimplemented target $p."
        exit 1
    fi

    #Ring requires SSE2 https://github.com/briansmith/ring/issues/1999#issuecomment-2151011318
    # See also https://salsa.debian.org/rust-team/debcargo-conf/-/blob/d586098f2597e5b5a1dcbf87af5268b3b84206e1/src/ring/debian/patches/use-generic-implementation-on-non-sse2-x86.patch
    # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1095863
    RUSTFLAGS=
    if [[ "$target" == "i586-unknown-linux-gnu" ]]; then
        RUSTFLAGS="-C target-feature=+sse,+sse2"
    fi

    # List of all crates that should be tested
    declare -a packages=("ctoolbox")

    # Try to set build concurrency to something reasonable
    export MAKEFLAGS="-j$(($(nproc)/2))"

    for i in "${packages[@]}"
    do
        pushd "$i" || exit 1
            
        # Run tests if RUST_LOG is set (to get more verbose output). By default
        # even debug tests are quiet.
        if [[ -n "${RUST_LOG-}" ]]; then
            RUST_LOG=debug RUSTFLAGS="$RUSTFLAGS -Awarnings" cargo test --target "$target" -- --test-threads 1 --nocapture || exit 1
            # cargo nextest does not support running doc tests so run them
            # separately if using it.
            # RUST_LOG=debug RUSTFLAGS="$RUSTFLAGS" cargo nextest run --profile default --target "$target" -- --nocapture || exit 1
            # RUST_LOG=debug RUSTFLAGS="$RUSTFLAGS" cargo test --target "$target" -- --test-threads 1 --nocapture --doc || exit 1
        else
            RUST_LOG=debug RUSTFLAGS="$RUSTFLAGS -Awarnings" cargo test --target "$target" -- --test-threads 4 || exit 1
            # cargo nextest does not support running doc tests so run them
            # separately if using it.
            # RUSTFLAGS="$RUSTFLAGS" cargo nextest run --profile default --target "$target" -- || exit 1
            # RUSTFLAGS="$RUSTFLAGS" cargo test --target "$target" -- --test-threads 3 --doc || exit 1
        fi

        # To build only the binary (and not the .so and .rlib files), add `--bins`, like `cargo build --bins`
        if [[ "$release" == "release" ]]; then
            RUSTFLAGS="$RUSTFLAGS" cargo build --bins --target "$target" --"$release"
        else
            # Cargo errors if you pass --debug for some reason
            # RUSTFLAGS="$RUSTFLAGS -Z instrument-mcount -C passes=ee-instrument<post-inline>" cargo build --features debug --bins --target "$target"
            RUSTFLAGS="$RUSTFLAGS -C passes=ee-instrument<post-inline>" cargo build --features debug --bins --target "$target"
        fi

        popd || exit 1

    done

    cp "ctoolbox/target/$target/$release/ctoolbox" built/"$platform"/
done

# cp built/web/vendor/coi-serviceworker/coi-serviceworker.js built/web/

# mv built/web/app.css built/web/app.in.css
# tailwindcss -i built/web/app.in.css -o built/web/app.css

find built/ -name '.gitignore' -delete

rm -r built/assets
mkdir -p built/assets
touch built/assets/.keep
