#!/usr/bin/env bash
#
# Copyright 2017-2025 AVSystem <avsystem@avsystem.com>
# AVSystem Anjay LwM2M SDK
# All rights reserved.
#
# Licensed under the AVSystem-5-clause License.
# See the attached LICENSE file for details.

. "$(dirname "$0")/tools/utils.sh"

SCRIPT_DIR="$(dirname "$(canonicalize "$0")")"
rm -rf avs_commons/install
rm -rf deps/avs_commons/CMakeFiles
rm -f deps/avs_commons/CMakeCache.txt

ANJAY_VERSION="unknown"

if [[ -d '.git' ]]; then
    echo "Updating submodules" && git submodule update --init --recursive || exit 1
    ANJAY_VERSION = $(git rev-parse --short HEAD)
fi

C_FLAGS='-g -std=c99 -Werror=implicit-function-declaration'

EXTRA_C_FLAGS=
EXTRA_FLAGS=()

MODULE_DYNAMIC_LIBS='ON'
MODULE_STATIC_LIBS='ON'
DTLS_BACKEND="mbedtls"
WITH_STATIC_ANALYSIS='ON'
WITH_EXAMPLES='ON'

if valgrind --version >/dev/null 2>/dev/null; then
    WITH_VALGRIND=ON
    WITH_ASAN=OFF
else
    WITH_VALGRIND=OFF
    WITH_ASAN=ON
fi

if ! which afl-gcc &>/dev/null; then
    if [[ -d "$HOME/tools/afl/latest" ]]; then
        AFL_FUZZER_DIR="$HOME/tools/afl/latest"
    fi
fi

# in case both CMake 2 and 3 is available, prefer newer
CMAKE_COMMAND=cmake
which cmake3 &>/dev/null && CMAKE_COMMAND=cmake3

# argument parsing
while [ $# -gt 0 ]; do
    case "$1" in
        '--c-flags')
            shift
            C_FLAGS="$1"
            ;;
        '--fuzz-tests')
            EXTRA_FLAGS[${#EXTRA_FLAGS[@]}]="-DCMAKE_TOOLCHAIN_FILE=$SCRIPT_DIR/cmake/toolchain/afl-gcc.cmake"
            EXTRA_FLAGS[${#EXTRA_FLAGS[@]}]="-DWITH_FUZZ_TESTS=ON"
            [[ "$AFL_FUZZER_DIR" ]] && EXTRA_FLAGS[${#EXTRA_FLAGS[@]}]="-DAFL_FUZZER_DIR=$AFL_FUZZER_DIR"
            ;;
        '--with-mbedtls')
            DTLS_BACKEND="mbedtls"
            ;;
        '--with-openssl')
            DTLS_BACKEND="openssl"
            ;;
        '--with-tinydtls')
            DTLS_BACKEND="tinydtls"
            ;;
        '--without-dtls')
            DTLS_BACKEND=
            ;;
        '--with-valgrind')
            WITH_ASAN=OFF
            WITH_VALGRIND=ON
            ;;
        '--with-asan')
            WITH_VALGRIND=OFF
            WITH_ASAN=ON
            ;;
        '--without-memcheck')
            WITH_ASAN=OFF
            WITH_VALGRIND=OFF
            ;;
        '--without-analysis')
            WITH_STATIC_ANALYSIS=OFF
            ;;
        '--no-examples')
            WITH_EXAMPLES=OFF
            ;;
        '--tiny')
            EXTRA_FLAGS[${#EXTRA_FLAGS[@]}]="-DMAX_PK_OR_IDENTITY_SIZE=256"
            EXTRA_FLAGS[${#EXTRA_FLAGS[@]}]="-DMAX_SECRET_KEY_SIZE=128"
            EXTRA_FLAGS[${#EXTRA_FLAGS[@]}]="-DMAX_DOUBLE_STRING_SIZE=64"
            EXTRA_FLAGS[${#EXTRA_FLAGS[@]}]="-DMAX_URI_SEGMENT_SIZE=64"
            EXTRA_FLAGS[${#EXTRA_FLAGS[@]}]="-DMAX_URI_QUERY_SEGMENT_SIZE=64"
            ;;
        -DDTLS_BACKEND=*)
            DTLS_BACKEND="${1#-DDTLS_BACKEND=}"
            ;;
        -D)
            if [[ $# -gt 1 && $2 =~ ^DTLS_BACKEND= ]]; then
                DTLS_BACKEND="${2#DTLS_BACKEND=}"
                shift
            else
                EXTRA_FLAGS[${#EXTRA_FLAGS[@]}]="$1"
            fi
            ;;
        *)
            EXTRA_FLAGS[${#EXTRA_FLAGS[@]}]="$1"
            ;;
    esac
    shift
done

if [ "$WITH_ASAN" == "ON" ]; then
    EXTRA_C_FLAGS="${EXTRA_C_FLAGS} -fsanitize=address"
fi

# use Homebrew-installed OpenSSL on macOS if available
BREW_OPENSSL="$(brew --prefix openssl 2>/dev/null)"
if [ "$BREW_OPENSSL" ]; then
    EXTRA_FLAGS[${#EXTRA_FLAGS[@]}]="-DOPENSSL_ROOT_DIR=$BREW_OPENSSL"
fi

# sysctl for macOS, nproc for most of everything else, echo 1 as a last resort
NPROC="$((nproc || sysctl -n hw.logicalcpu || echo 1) 2>/dev/null)"

rm -f CMakeCache.txt
rm -rf CMakeFiles
${CMAKE_COMMAND} \
    -D WITH_TEST=ON \
    -D WITH_LICENSE_TEST=ON \
    -D WITH_DEMO=ON \
    -D WITH_EXTRA_WARNINGS=ON \
    -D WITH_CON_ATTR=ON \
    -D WITH_HTTP_DOWNLOAD=ON \
    -D WITH_THREAD_SAFETY=ON \
    -D WITH_VALGRIND=${WITH_VALGRIND} \
    -D WITH_INTEGRATION_TESTS=ON \
    -D WITH_DOC_CHECK=ON \
    -D WITH_URL_CHECK=ON \
    -D WITH_STATIC_ANALYSIS=${WITH_STATIC_ANALYSIS} \
    -D WITH_MODULE_advanced_fw_update=ON \
    -D WITH_MODULE_sw_mgmt=ON \
    -D DTLS_BACKEND="${DTLS_BACKEND}" \
    -D AVS_LOG_WITH_TRACE=ON \
    -D WITH_EXAMPLES=${WITH_EXAMPLES} \
    -D CMAKE_C_FLAGS="${C_FLAGS} ${EXTRA_C_FLAGS}" \
    -D CMAKE_CXX_FLAGS="${EXTRA_C_FLAGS}" \
    -D ANJAY_VERSION="${ANJAY_VERSION}" \
    -D NPROC="$((3 * NPROC))" \
    "${EXTRA_FLAGS[@]}" \
    -H"$(dirname "$0")" -B. &&
make clean