#!/usr/bin/env bash
#
# Parameters:
#   CMAKE_TARGET -- use $CMAKE_TARGET.cmake as toolchain file
#   AES_NI=1 -- enable AES_NI processor optimization
#   EXTERNAL_RNG=1 -- disable all internal RNG implementations (caller must provide)
#   ENABLE_TESTING=1 -- run PolarSSL test scripts after build
#   DEBUG_BUILD=1 or SELF_TEST=1 -- enable minimal testing on target
#   ENABLE_SERVER=1  -- enable SSL/TLS server code
#   ENABLE_FS_IO=1 -- enable PolarSSL file I/O
#   VERBOSE=1 -- see build commands
#   USE_MINICRYPTO=1 -- use minicrypto library
#   NO_WIPE=1 -- don't wipe source tree and reunzip tarball
#   STOCK_CONFIG=1 -- use stock PolarSSL config.h

set -e
if [ -z "$O3" ]; then
    echo O3 var must point to ovpn3 tree
    exit 1
fi
if [ -z "$TARGET" ]; then
    echo TARGET var must be defined
    exit 1
fi

# source vars
. $O3/core/vars/vars-${TARGET}
. $O3/core/deps/lib-versions

# extract the PolarSSL source
PD=$O3/core/deps/polarssl
DIST=polarssl-$PLATFORM

rm -rf $DIST
mkdir $DIST

if [ "$NO_WIPE" = "1" ]; then
    echo RETAIN existing source
    cd $POLARSSL_VERSION
elif [ "$NO_WIPE" = "partial" ]; then
    echo RETAIN existing source but copy config.h and CMakeLists.txt
    cd $POLARSSL_VERSION

    # define configs
    if [ "$STOCK_CONFIG" != "1" ]; then
	cp $PD/config.h include/polarssl/
    fi
    cp $PD/CMakeLists.txt .
else
    echo WIPE and reunzip source
    rm -rf $POLARSSL_VERSION $POLARSSL_VERSION-prerelease
    [ -z "$DL" ] && DL=~/Downloads
    tar xfz $DL/$POLARSSL_VERSION-gpl.tgz

    [ -d $POLARSSL_VERSION-prerelease ] && mv $POLARSSL_VERSION-prerelease $POLARSSL_VERSION
    cd $POLARSSL_VERSION

    # delete makefiles (apparently not needed)
    rm $(find . -type f | grep Makefile)

    patch -p1 <$PD/relaxed-x509-date.patch
    #patch -p1 <$PD/dhm.patch
    #patch -p1 <$PD/entropy-printf.patch

    if [ "$USE_MINICRYPTO" = "1" ]; then
        # do the big polar-openssl patch
	echo MERGING polarssl-minicrypto.patch
	patch -p1 <$PD/polarssl-minicrypto.patch
    fi

    # define configs
    cp include/polarssl/config.h include/polarssl/config.h.orig
    cp CMakeLists.txt CMakeLists.txt.orig
    cp $PD/config.h include/polarssl/
    cp $PD/CMakeLists.txt .
fi

# dynamically generated header file with options,
# included by config.h
OPC=include/polarssl/openvpn-polarssl.h
echo '/* Automatically generated by ovpn3/core/deps/polarssl/build-polarssl, do not edit */' >$OPC

# set options
OPT=""

# relaxed cert checking
echo "#define POLARSSL_RELAXED_X509_DATE" >>$OPC

# RNG
if [ "$EXTERNAL_RNG" = "1" ]; then
    echo "#define EXTERNAL_RNG" >>$OPC
fi

# enable full testing infrastructure
if [ "$ENABLE_TESTING" = "1" ]; then
    OPT="$OPT -DENABLE_TESTING=1"
    echo "#define ENABLE_TESTING" >>$OPC
fi

# enable minimal testing on target
if [ "$DEBUG_BUILD" = "1" ] || [ "$SELF_TEST" = "1" ]; then
    echo "#define POLARSSL_SELF_TEST" >>$OPC
fi

# configure target
if [ "$CMAKE_TARGET" ]; then
    OPT="$OPT -DCMAKE_TOOLCHAIN_FILE=$PD/$CMAKE_TARGET.cmake"
elif [ "$APPLE_FAMILY" = "1" ]; then
    OPT="$OPT -DCMAKE_TOOLCHAIN_FILE=$PD/apple.cmake"
fi

# Minicrypto
if [ "$USE_MINICRYPTO" = "1" ]; then
    OPT="$OPT -DMINICRYPTO=1"
    if [ "$MINICRYPTO_DIR" ]; then
	OPT="$OPT -DMINICRYPTO_DIR=$MINICRYPTO_DIR"
    fi
    if [ "$OSSLCRYPTO_DIR" ]; then
	OPT="$OPT -DOSSLCRYPTO_DIR=$OSSLCRYPTO_DIR"
    fi
    if [ "$MINICRYPTO_NO_AES" != "1" ]; then
	echo "#define POLARSSL_AES_ALT" >>$OPC
    fi
    echo "#define POLARSSL_SHA1_ALT" >>$OPC
    echo "#define POLARSSL_SHA256_ALT" >>$OPC
    echo "#define POLARSSL_SHA512_ALT" >>$OPC
    if [ "$AES_NI" = "1" ] && [ "$MINICRYPTO_NO_AES" != "1" ]; then
	echo "#define POLARSSL_USE_OPENSSL_AES_NI" >>$OPC
    fi
fi

# Enable SSL/TLS server
if [ "$ENABLE_SERVER" = "1" ]; then
    echo "#define POLARSSL_SSL_SRV_C" >>$OPC
fi

# enable PolarSSL file I/O
if [ "$ENABLE_FS_IO" = "1" ]; then
    echo "#define POLARSSL_FS_IO" >>$OPC
fi

# Build shared library
if [ "$SHARED" = "1" ]; then
    OPT="$OPT -DUSE_SHARED_POLARSSL_LIBRARY=1"
fi

# echo options
echo OPTIONS $OPT

# build it
pwd
cd ../$DIST
cmake $OPT ../$POLARSSL_VERSION
if [ "$VERBOSE" = "1" ]; then
    make VERBOSE=1
else
    make
fi

# test it
if [ "$ENABLE_TESTING" = "1" ]; then
    make test
fi

# copy headers
cp -a ../$POLARSSL_VERSION/include/polarssl include/
exit 0
