#!/bin/sh

set -e
set -u

if command -v clang >/dev/null 2>&1; then
    CC="${CC:-clang}"
    CXX="${CXX:-clang++}"
elif command -v gcc >/dev/null 2>&1; then
    CC="${CC:-gcc}"
    CXX="${CXX:-g++}"
elif command -v cc >/dev/null 2>&1; then
    CC="${CC:-cc}"
    CXX="${CXX:-c++}"
fi

STRIP="${STRIP:-strip}"
AR="${AR:-ar}"
AREXTRACTFLAGS="${AREXTRACTFLAGS:--x}"
ARLISTFLAGS="${ARLISTFLAGS:--t}"
ARCOLLECTFLAGS="${ARCOLLECTFLAGS:-cqS}"
# this is the command to build the symbol table in an ar archive.
ARBUILDSYMBOLS="${ARBUILDSYMBOLS:-ranlib}"
FIND="${FIND:-find}"
STRIP_NEEDS_EXTRACT="${STRIP_NEEDS_EXTRACT:-n}"

triple=$(${CC} -dumpmachine)
host_platform="${triple}"
target_platform="${TARGET_PLATFORM:-${1:-}}"
target_platform="${target_platform:-${host_platform}}"

case "${target_platform}" in
    x86_64*-linux-musl)
        RUBY_TARGET_PLATFORM='x86_64-linux-musl'
        ;;
    x86_64*-linux-*)
        RUBY_TARGET_PLATFORM='x86_64-linux'
        ;;
    aarch64*-linux-musl)
        RUBY_TARGET_PLATFORM='aarch64-linux-musl'
        ;;
    aarch64*-linux-*)
        RUBY_TARGET_PLATFORM='aarch64-linux'
        ;;
    arm*-linux-musl)
        RUBY_TARGET_PLATFORM='arm-linux-musl'
        ;;
    arm*-linux-*)
        RUBY_TARGET_PLATFORM='arm-linux'
        ;;
    x86_64*-darwin*)
        # not for cross compilation
        RUBY_TARGET_PLATFORM='x86_64-darwin'
        ;;
    arm64*-darwin*)
        # not for cross compilation
        RUBY_TARGET_PLATFORM='arm64-darwin'
        ;;
    *)
        if [ "${host_platform}" != "${target_platform}" ]; then
            echo 'cross compilation not supported'
            exit 1
        fi
        RUBY_TARGET_PLATFORM="$(ruby -e 'puts Gem::Platform.local.to_s')"
        ;;
esac

case "${host_platform}" in
    *solaris*)
        CC="${CC:-/opt/local/gcc7/bin/gcc}"
        CXX="${CXX:-/opt/local/gcc7/bin/g++}"
        STRIP="gstrip"
        ;;
    *linux*)
        STRIP_NEEDS_EXTRACT="y"
        ARCOLLECTFLAGS="-cqSP"
        ARBUILDSYMBOLS="${AR} -sP"
        ;;
esac

if [ "${host_platform}" != "${target_platform}" ]; then
    echo "# cross compiling host: ${host_platform} target: ${target_platform}"
    case "${target_platform}" in
        aarch64-*linux*)
            CC='aarch64-linux-gnu-gcc'
            CXX='aarch64-linux-gnu-g++'
            CC_host='gcc'
            CXX_host='g++'
            STRIP='aarch64-linux-gnu-strip'
            configure_flags='--dest-cpu=arm64 --cross-compiling --dest-os=linux --with-arm-float-abi=hard --with-arm-fpu=neon'
            ;;
        arm*-*linux*)
            CC='arm-linux-gnueabihf-gcc'
            CXX='arm-linux-gnueabihf-g++'
            CC_host='gcc -m32'
            CXX_host='g++ -m32'
            STRIP='arm-linux-gnueabihf-strip'
            configure_flags='--dest-cpu=arm --cross-compiling --dest-os=linux --with-arm-float-abi=hard --with-arm-fpu=neon'
            ;;
        x86_64-*linux*)
            CC='x86_64-linux-gnu-gcc'
            CXX='x86_64-linux-gnu-g++'
            CC_host='gcc'
            CXX_host='g++'
            STRIP='x86_64-linux-gnu-strip'
            configure_flags='--dest-cpu=x86_64 --cross-compiling --dest-os=linux'
            ;;
        x86_64*-darwin*)
            CC='clang -arch x86_64'
            CXX='clang++ -arch x86_64'
            CC_host='clang'
            CXX_host='clang++'
            STRIP='strip'
            configure_flags='--dest-cpu=x86_64 --cross-compiling --dest-os=mac'
            ;;
        arm64*-darwin*)
            CC='clang -arch arm64'
            CXX='clang++ -arch arm64'
            CC_host='clang'
            CXX_host='clang++'
            STRIP='strip'
            configure_flags='--dest-cpu=arm64 --cross-compiling --dest-os=mac'
            ;;
        *)
            configure_flags=''
            ;;
    esac
else
    configure_flags=''
fi

# TODO: building with pointer compression is broken
# case "${target_platform}" in
#     arm64-*)
#         configure_flags="${configure_flags} --experimental-enable-pointer-compression"
#         ;;
#     arm*-*linux*)
#         :
#         ;;
#     *)
#         configure_flags="${configure_flags} --experimental-enable-pointer-compression"
#         ;;
# esac

if command -v ccache >/dev/null 2>&1; then
    if [ -n "${CC:-}" ] && [ "${CC}" = "${CC#ccache}" ]; then
        CC="ccache ${CC}"
        CXX="ccache ${CXX}"
    fi

    if [ -n "${CC_host:-}" ] && [ "${CC_host}" = "${CC_host#ccache}" ]; then
        CC_host="ccache ${CC_host}"
        CXX_host="ccache ${CXX_host}"
    fi
fi

cat <<EOF
export CC='${CC}'
export CXX='${CXX}'
host_platform='${host_platform}'
target_platform='${target_platform}'
STRIP='$STRIP'
AR='$AR'
AREXTRACTFLAGS='$AREXTRACTFLAGS'
ARLISTFLAGS='$ARLISTFLAGS'
ARCOLLECTFLAGS='$ARCOLLECTFLAGS'
ARBUILDSYMBOLS='$ARBUILDSYMBOLS'
FIND='$FIND'
STRIP_NEEDS_EXTRACT='$STRIP_NEEDS_EXTRACT'
EOF

if [ -n "${CC_host:-}" ]; then cat <<EOF; fi
export CC_host='${CC_host}'
export CXX_host='${CXX_host}'
EOF

if [ -n "${STRIP:-}" ]; then cat <<EOF; fi
STRIP='${STRIP}'
EOF

if [ -n "${RUBY_TARGET_PLATFORM:-}" ]; then cat <<EOF; fi
RUBY_TARGET_PLATFORM='${RUBY_TARGET_PLATFORM}'
EOF

if [ -n "${configure_flags:-}" ]; then cat <<EOF; fi
configure_flags="\${configure_flags:-} ${configure_flags}"
EOF
