#!/usr/bin/env bash

set -e

DL="${DL:-/tmp/dl}"
DEP_DIR_PREFIX=$PWD/deps
CMAKE_C_COMPILER="w64-mingw32-gcc-posix"
CMAKE_CXX_COMPILER="w64-mingw32-g++-posix"
ARCH=${ARCH:-i686 x86_64}

download_deps()
{
    if [ -n "$NO_DEPS" ]; then
        echo "Skip dependencies download"
        return
    fi

    pushd $DL

    rm -rf lz4
    git clone https://github.com/lz4/lz4.git

    rm -rf jsoncpp
    git clone https://github.com/open-source-parsers/jsoncpp.git

    if [ -z "$NO_OPENSSL" ]; then
        rm -rf openssl
        git clone --single-branch --branch OpenSSL_1_1_1-stable https://github.com/openssl/openssl.git
    fi

    rm -rf tap-windows6
    git clone https://github.com/OpenVPN/tap-windows6.git

    rm -rf asio
    git clone --single-branch --branch asio-1-16-1 https://github.com/chriskohlhoff/asio

    popd
}

build_lz4()
{
    ARCH=$1

    pushd $DL/lz4

    mkdir build-${ARCH}
    cd build-${ARCH}

    cmake -D CMAKE_C_COMPILER=$ARCH-$CMAKE_C_COMPILER \
          -D CMAKE_SYSTEM_NAME=Windows \
          -D CMAKE_INSTALL_PREFIX=$DEP_DIR_PREFIX-$ARCH \
          ../build/cmake/
    make && make install

    popd
}

build_jsoncpp()
{
    ARCH=$1

    pushd $DL/jsoncpp

    mkdir build-${ARCH}
    cd build-${ARCH}

    cmake -D CMAKE_CXX_COMPILER=$ARCH-$CMAKE_CXX_COMPILER \
          -D CMAKE_SYSTEM_NAME=Windows \
          -D CMAKE_INSTALL_PREFIX=$DEP_DIR_PREFIX-$ARCH \
          -D JSONCPP_WITH_TESTS=false \
          -D BUILD_SHARED_LIBS=true \
          -D CMAKE_BUILD_TYPE=Release \
          ..
    make && make install

    popd
}

build_openssl()
{
    if [ -n "$NO_OPENSSL" ]; then
        echo "Skip OpenSSL build"
        return
    fi

    ARCH=$1

    pushd $DL/openssl

    [ "$ARCH" == "x86_64" ] && OUT="mingw64" || OUT="mingw"
    make clean || true
    ./Configure --prefix=$DEP_DIR_PREFIX-$ARCH no-idea no-mdc2 no-rc5 shared $OUT --cross-compile-prefix=$ARCH-w64-mingw32-
    make && make -j1 install || true

    popd
}

build_tap_windows6()
{
    ARCH=$1

    cp $DL/tap-windows6/src/tap-windows.h $DEP_DIR_PREFIX-$ARCH/include
}

build_asio()
{
    ARCH=$1

    mkdir -p $DEP_DIR_PREFIX-$ARCH/asio
    cp -R $DL/asio/* $DEP_DIR_PREFIX-$ARCH/asio
}

build_deps()
{
    if [ -n "$NO_DEPS" ]; then
        echo "Skip dependencies build"
        return
    fi

    ARCH=$1

    echo "Building deps for $arch"

    mkdir -p $DEP_DIR_PREFIX-$ARCH

    build_lz4 $ARCH
    build_jsoncpp $ARCH
    build_tap_windows6 $ARCH
    build_asio $ARCH
    build_openssl $ARCH
}

build_core()
{
    ARCH=$1

    echo "Building core for $arch"

    rm -rf build-$ARCH
    mkdir build-$ARCH

    CORE_DIR=$(dirname $(realpath -s $0))/../..

    pushd build-$ARCH

    DEP_DIR=$DEP_DIR_PREFIX-$ARCH \
    OPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR:-$DEP_DIR_PREFIX-$ARCH} \
    cmake -D CMAKE_C_COMPILER=$ARCH-$CMAKE_C_COMPILER \
          -D CMAKE_CXX_COMPILER=$ARCH-$CMAKE_CXX_COMPILER \
          -D CMAKE_SYSTEM_NAME=Windows \
          -D CMAKE_PREFIX_PATH=/usr/local/$ARCH-w64-mingw32 \
          -D CMAKE_BUILD_TYPE=Release \
          -D USE_WERROR=true \
          $CORE_DIR

    make

    popd
}

mkdir -p $DL

download_deps
for arch in $ARCH
do
    echo "Building for $arch"
    build_deps $arch
    build_core $arch
done
