#!/usr/bin/env sh

# Obtain location of source root.
src_root () {
	local SCRIPT_LOCATION=""
	local SYSTEM=$(uname -s)
	if [ ! "x${SYSTEM}" = "xDarwin" ]; then
		local SCRIPT=$(readlink -f "$0")
		SCRIPT_LOCATION=$(dirname $(readlink -f "$0"))
	else
		SCRIPT_LOCATION=$(cd "$(dirname "$0")"; pwd)
	fi

	echo $(cd "$(dirname "${SCRIPT_LOCATION}")"; pwd)
}

SRC_ROOT=$(src_root)

if [ "x${GETOPT}" = "x" ]; then
	GETOPT="getopt"
fi

USAGE="Usage:\n\t$0 [options]\n\n"
USAGE="${USAGE}Supported options:\n"
USAGE="${USAGE}\t-h, --help\n\t\tPrints help message.\n"
USAGE="${USAGE}\t--i386 (default)\n\t\tCompile for the i386 architecture.\n"
USAGE="${USAGE}\t--x86_64\n\t\tCompile for the x86_64 architecture.\n"

cd "${SRC_ROOT}"

ARCH_NAME=""
ARCH_I386="i386"
ARCH_X86_64="x86_64"

if ! "${GETOPT}" -l test: -u -o t: -- --test test > /dev/null; then
	echo "The default getopt does not support long options." >&2
	echo "You may provide such getopt version via the GETOPT variable e.g.:" >&2
	echo "GETOPT=/opt/local/bin/getopt $0" >&2
	exit 1
fi

# Parse rest of command line
set -- $("${GETOPT}" -l help -l i386 -l x86_64 -u -o h -- "$@")
if [ $# -lt 1 ]; then
	echo -e ${USAGE} >&2
	exit 1
fi

while [ $# -gt 0 ]; do
	OPTION="$1"
	PARAM="$2"
	case "${OPTION}" in
	-h|--help)
		echo -e ${USAGE}
		exit 0
		;;
	--i386)
		if [ "x${ARCH_NAME}" = "x" ]; then
			ARCH_NAME="${ARCH_I386}"
		else
			echo "Architecture already specified or in conflict." >&2
			exit 1
		fi
		;;
	--x86_64)
		if [ "x${ARCH_NAME}" = "x" ]; then
			ARCH_NAME="${ARCH_X86_64}"
		else
			echo "Architecture already specified or in conflict." >&2
			exit 1
		fi
		;;
	--)
		shift
		break
		;;
	-*|*)
		echo "Unknown option '${OPTION}'." >&2
		echo -e ${USAGE} >&2
		exit 1
		;;
	esac
	unset OPTION
	unset PARAM
	shift
done
if [ $# -gt 0 ]; then
	echo -e "Unknown options: $@" >&2
	echo -en ${USAGE} >&2
	exit 1
fi

# Use i386 by default.
if [ "x${ARCH_NAME}" = "x" ]; then
	ARCH_NAME="${ARCH_I386}"
fi

. "${SRC_ROOT}"/scripts/helper_dependency_sources.sh
. "${SRC_ROOT}"/scripts/helper_git.sh

if [ "x${ARCH_NAME}" = "x${ARCH_I386}" ]; then
	adjust_sources "mingw32"
elif [ "x${ARCH_NAME}" = "x${ARCH_X86_64}" ]; then
	adjust_sources "mingw64"
else
	echo "Unknown architecture." >&2
	exit 1
fi

WIN_VER="0x0501" #https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745%28v=vs.85%29.aspx
MAKEOPTS="-j 4"

LIB_ROOT="${SRC_ROOT}"/libs
mkdir -p "${LIB_ROOT}"
if [ ! -d "${LIB_ROOT}" ]; then
	echo "Cannot find directory '${LIB_ROOT}'" >&2
	exit 1
fi
cd "${LIB_ROOT}"


WIN_MAKE=mingw32-make.exe
runnning_on_win () {
	local FOUND_WIN_MAKE=$(which "${WIN_MAKE}")
	if [ "x${FOUND_WIN_MAKE}" != "x" ]; then
		echo "true"
	else
		echo "false"
	fi
}
RUNNING_ON_WIN=$(runnning_on_win)

SRCDIR="${LIB_ROOT}/srcs"
PATCHDIR="${SRC_ROOT}/scripts/patches"
WORKDIR_PREFIX="${LIB_ROOT}/work"
BUILTDIR_PREFIX="${LIB_ROOT}/built"

X86_MINGV_HOST=""
OPENSSL_MINGW_CONFOPT=""

if [ "x${ARCH_NAME}" = "x${ARCH_I386}" ]; then
	#X86_MINGV_HOST=i586-mingw32msvc # This old compiler chain isn't available on newer distros.
	X86_MINGV_HOST=i686-w64-mingw32

	OPENSSL_MINGW_CONFOPT="mingw"
elif [ "x${ARCH_NAME}" = "x${ARCH_X86_64}" ]; then
	X86_MINGV_HOST=x86_64-w64-mingw32

	OPENSSL_MINGW_CONFOPT="mingw64"
fi

X86_MINGW_PREFIX=${X86_MINGV_HOST}-
X86_MINGW_CC=${X86_MINGV_HOST}-gcc
X86_MINGW_CXX=${X86_MINGV_HOST}-g++
X86_MINGW_LD=${X86_MINGV_HOST}-ld
X86_MINGW_STRIP=${X86_MINGV_HOST}-strip
X86_MINGW_RANLIB=${X86_MINGV_HOST}-ranlib

if ! command -v "${X86_MINGW_CC}" 2>&1 1>/dev/null; then
	echo "Cannot find command '${X86_MINGW_CC}'." >&2
	exit 1
fi

if [ "x${RUNNING_ON_WIN}" != "xtrue" ]; then
	WORKDIR_PREFIX="${WORKDIR_PREFIX}_${X86_MINGV_HOST}"
	BUILTDIR_PREFIX="${BUILTDIR_PREFIX}_${X86_MINGV_HOST}"
else
	X86_MINGV_HOST=""
	WORKDIR_PREFIX="${WORKDIR_PREFIX}_qt-mingw"
	BUILTDIR_PREFIX="${BUILTDIR_PREFIX}_qt-mingw"
	echo "The libraries cannot be currently built on Windows." >&2
	exit 1
fi

if [ ! -d "${SRCDIR}" ]; then
	mkdir "${SRCDIR}"
fi

download_all_sources "${SRCDIR}" || exit 1
sleep 3

# Specifies which targets to build.
TARGETS=""
#TARGETS="${TARGETS} static"
TARGETS="${TARGETS} shared"

# Return 0 if targets are OK.
check_params () {
	local TYPE="$1"
	if [ "x${TYPE}" != "xstatic" -a "x${TYPE}" != "xshared" ]; then
		echo "Unknown type '${TYPE}'." >&2
		return 1
	fi
	return 0
}

# Return 0 if target is scheduled for build.
target_scheduled () {
	local TYPE="$1"
	check_params "${TYPE}" || return 1
	local RES=""
	RES=$(echo "${TARGETS}" | grep "${TYPE}")
	if [ "x${RES}" != "x" ]; then
		return 0
	else
		return 1
	fi
}

workdir_name () {
	local TYPE="$1"
	echo "${WORKDIR_PREFIX}_${TYPE}"
}

builtdir_name () {
	local TYPE="$1"
	echo "${BUILTDIR_PREFIX}_${TYPE}"
}

ensure_dir_presence () {
	mkdir -p "$1"
}

# Create missing directories.
target_scheduled static && ensure_dir_presence $(workdir_name static)
target_scheduled static && ensure_dir_presence $(builtdir_name static)
target_scheduled shared && ensure_dir_presence $(workdir_name shared)
target_scheduled shared && ensure_dir_presence $(builtdir_name shared)

# Store information about build.
store_build_info () {
	local TYPE="$1"
	check_params "${TYPE}" || exit 1
	local BUILTDIR=$(builtdir_name "${TYPE}")

	${X86_MINGW_PREFIX}gcc -v 2> "${BUILTDIR}/gcc-version.txt"
	${X86_MINGW_PREFIX}g++ -v 2> "${BUILTDIR}/g++-version.txt"
	# Curly brackets don't work in plain Bourne shell.
	#cat /etc/*{release,version} > "${BUILTDIR}/linux-version.txt"
	cat /etc/*release /etc/*version > "${BUILTDIR}/linux-version.txt"
	uname -a > "${BUILTDIR}/uname.txt"
	git log -n 1 --pretty=format:"%h - %ad : %s" > "${BUILTDIR}/git.txt"
}

target_scheduled static && store_build_info static
target_scheduled shared && store_build_info shared


ZLIB_ARCHIVE="${_ZLIB_ARCHIVE}"
EXPAT_ARCHIVE="${_EXPAT_ARCHIVE}"
LIBTOOL_ARCHIVE="${_LIBTOOL_ARCHIVE}"

LIBICONV_ARCHIVE="${_LIBICONV_ARCHIVE}"
LIBXML2_ARCHIVE="${_LIBXML2_ARCHIVE}"
GETTEXT_ARCHIVE="${_GETTEXT_ARCHIVE}" # Enable NLS.

LIBCURL_ARCHIVE="${_LIBCURL_ARCHIVE}"
OPENSSL_ARCHIVE="${_OPENSSL_ARCHIVE}"
OPENSSL_ARCHIVE_PATCHES=${_OPENSSL_ARCHIVE_PATCHES}
JSON_C_ARCHIVE=${_JSON_C_ARCHIVE}
JSON_C_ARCHIVE_PATCHES=${_JSON_C_ARCHIVE_PATCHES}

LIBDATOVKA_ARCHIVE="${_LIBDATOVKA_ARCHIVE}"
LIBDATOVKA_ARCHIVE_PATCHES="${_LIBDATOVKA_ARCHIVE_PATCHES}"
#LIBDATOVKA_GIT="https://gitlab.nic.cz/datovka/libdatovka.git"
#LIBDATOVKA_BRANCH="master"


build_zlib () {
	local TYPE="$1"
	check_params "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${TYPE}")
	local BUILTDIR=$(builtdir_name "${TYPE}")

	erase_and_decompress "${SRCDIR}" "${ZLIB_ARCHIVE}" "${WORKDIR}" zlib
	cd "${WORKDIR}"/zlib*

	local SHARED="1"
	if [ "x${TYPE}" = "xstatic" ]; then
		SHARED="0"
	fi

	make ${MAKEOPTS} -f win32/Makefile.gcc \
	    SHARED_MODE=${SHARED} \
	    PREFIX=${X86_MINGW_PREFIX} \
	    BINARY_PATH=${BUILTDIR}/bin \
	    INCLUDE_PATH=${BUILTDIR}/include \
	    LIBRARY_PATH=${BUILTDIR}/lib \
	    install || exit 1

	if [ "x${TYPE}" = "xshared" ]; then
		rm -rf "${BUILTDIR}"/lib/libz.a
	fi

	return 0
}

if [ ! -z "${ZLIB_ARCHIVE}" ]; then
	echo "Building zlib."
	if target_scheduled static; then build_zlib static || exit 1; fi
	if target_scheduled shared; then build_zlib shared || exit 1; fi
fi


build_expat () {
	local TYPE="$1"
	check_params "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${TYPE}")
	local BUILTDIR=$(builtdir_name "${TYPE}")

	erase_and_decompress "${SRCDIR}" "${EXPAT_ARCHIVE}" "${WORKDIR}" expat
	cd "${WORKDIR}"/expat*

	local CONFOPTS=""
	CONFOPTS="${CONFOPTS} --prefix=${BUILTDIR}"
	if [ "x${TYPE}" = "xstatic" ]; then
		CONFOPTS="${CONFOPTS} --disable-shared"
	fi
	if [ "x${TYPE}" = "xshared" ]; then
		CONFOPTS="${CONFOPTS} --disable-static"
	fi

	./configure ${CONFOPTS} --host="${X86_MINGV_HOST}"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS

	return 0
}

if [ ! -z "${EXPAT_ARCHIVE}" ]; then
	echo "Building expat."
	if target_scheduled static; then build_expat static || exit 1; fi
	if target_scheduled shared; then build_expat shared || exit 1; fi
fi


build_libtool () {
	local TYPE="$1"
	check_params "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${TYPE}")
	local BUILTDIR=$(builtdir_name "${TYPE}")

	erase_and_decompress "${SRCDIR}" "${LIBTOOL_ARCHIVE}" "${WORKDIR}" libtool
	cd "${WORKDIR}"/libtool*

	local CONFOPTS=""
	CONFOPTS="${CONFOPTS} --prefix=${BUILTDIR}"
	if [ "x${TYPE}" = "xstatic" ]; then
		CONFOPTS="${CONFOPTS} --disable-shared"
	fi
	if [ "x${TYPE}" = "xshared" ]; then
		CONFOPTS="${CONFOPTS} --disable-static"
	fi

	./configure ${CONFOPTS} --host="${X86_MINGV_HOST}"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS

	return 0
}

if [ ! -z "${LIBTOOL_ARCHIVE}" ]; then
	echo "Building libtool."
	if target_scheduled static; then build_libtool static || exit 1; fi
	if target_scheduled shared; then build_libtool shared || exit 1; fi
fi


build_libiconv () {
	local TYPE="$1"
	check_params "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${TYPE}")
	local BUILTDIR=$(builtdir_name "${TYPE}")

	erase_and_decompress "${SRCDIR}" "${LIBICONV_ARCHIVE}" "${WORKDIR}" libiconv
	cd "${WORKDIR}"/libiconv*

	local CONFOPTS=""
	CONFOPTS="${CONFOPTS} --prefix=${BUILTDIR}"
	if [ "x${TYPE}" = "xstatic" ]; then
		CONFOPTS="${CONFOPTS} --disable-shared"
	fi
	if [ "x${TYPE}" = "xshared" ]; then
		CONFOPTS="${CONFOPTS} --disable-static"
	fi

	./configure ${CONFOPTS} --host="${X86_MINGV_HOST}"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS

	return 0
}

if [ ! -z "${LIBICONV_ARCHIVE}" ]; then
	echo "Building libiconv."
	if target_scheduled static; then build_libiconv static || exit 1; fi
	if target_scheduled shared; then build_libiconv shared || exit 1; fi
fi


build_libxml2 () {
	local TYPE="$1"
	check_params "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${TYPE}")
	local BUILTDIR=$(builtdir_name "${TYPE}")

	erase_and_decompress "${SRCDIR}" "${LIBXML2_ARCHIVE}" "${WORKDIR}" libxml2
	cd "${WORKDIR}"/libxml2*

	local CONFOPTS=""
	CONFOPTS="${CONFOPTS} --prefix=${BUILTDIR}"
	if [ "x${TYPE}" = "xstatic" ]; then
		CONFOPTS="${CONFOPTS} --disable-shared"
	fi
	if [ "x${TYPE}" = "xshared" ]; then
		CONFOPTS="${CONFOPTS} --disable-static"
	fi
	CONFOPTS="${CONFOPTS} --without-lzma"
	CONFOPTS="${CONFOPTS} --without-zlib"
	CONFOPTS="${CONFOPTS} --without-python"
	CONFOPTS="${CONFOPTS} --with-iconv=${BUILTDIR}"

	./configure ${CONFOPTS} --host="${X86_MINGV_HOST}"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS

	return 0
}

if [ ! -z "${LIBXML2_ARCHIVE}" ]; then
	echo "Bulding libxml2."
	if target_scheduled static; then build_libxml2 static || exit 1; fi
	if target_scheduled shared; then build_libxml2 shared || exit 1; fi
fi


build_gettext () {
	local TYPE="$1"
	check_params "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${TYPE}")
	local BUILTDIR=$(builtdir_name "${TYPE}")

	erase_and_decompress "${SRCDIR}" "${GETTEXT_ARCHIVE}" "${WORKDIR}" gettext
	cd "${WORKDIR}"/gettext*

	local CONFOPTS=""
	CONFOPTS="${CONFOPTS} --prefix=${BUILTDIR}"
	if [ "x${TYPE}" = "xstatic" ]; then
		CONFOPTS="${CONFOPTS} --disable-shared"
	fi
	if [ "x${TYPE}" = "xshared" ]; then
		CONFOPTS="${CONFOPTS} --disable-static"
	fi
	CONFOPTS="${CONFOPTS} --with-libxml2-prefix=${BUILTDIR}"
	CONFOPTS="${CONFOPTS} --with-libiconv-prefix=${BUILTDIR}"
	CONFOPTS="${CONFOPTS} --enable-relocatable"
	CONFOPTS="${CONFOPTS} --enable-threads=win32"

	local DEFINES=""
	if [ "x${TYPE}" = "xstatic" ]; then
		DEFINES="${DEFINES} -DLIBXML_STATIC"
	fi

	./configure ${CONFOPTS} --host="${X86_MINGV_HOST}" \
	    CPPFLAGS="-I${BUILTDIR}/include ${DEFINES}" \
	    LDFLAGS="-L${BUILTDIR}/lib"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS
	unset DEFINES

	return 0
}

if [ ! -z "${GETTEXT_ARCHIVE}" ]; then
	echo "Building gettext."
	if target_scheduled static; then build_gettext static || exit 1; fi
	if target_scheduled shared; then build_gettext shared || exit 1; fi
fi


build_openssl () {
	local TYPE="$1"
	check_params "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${TYPE}")
	local BUILTDIR=$(builtdir_name "${TYPE}")

	erase_and_decompress "${SRCDIR}" "${OPENSSL_ARCHIVE}" "${WORKDIR}" openssl
	cd "${WORKDIR}"/openssl*

	if [ "x${OPENSSL_ARCHIVE_PATCHES}" != "x" ]; then
		# Apply patches.
		for f in ${OPENSSL_ARCHIVE_PATCHES}; do
			local PATCHFILE="${PATCHDIR}/${f}"
			if [ ! -f "${PATCHFILE}" ]; then
				echo "Missing ${PATCHFILE}" >&2
				exit 1
			fi
			cp "${PATCHFILE}" ./
			echo "Applying ${f}"
			patch -p1 < ${f}
			unset PATCHFILE
		done
	fi

	local CONFOPTS=""
	#CONFOPTS="${CONFOPTS} no-asm"
	CONFOPTS="${CONFOPTS} ${OPENSSL_MINGW_CONFOPT}"
	CONFOPTS="${CONFOPTS} enable-static-engine"
	if [ "x${TYPE}" = "xstatic" ]; then
		CONFOPTS="${CONFOPTS} no-shared"
	fi
	if [ "x${TYPE}" = "xshared" ]; then
		CONFOPTS="${CONFOPTS} shared"
	fi
	#CONFOPTS="${CONFOPTS} no-krb5" # OpenSSL-1.1.x does not know this parameter.

	./Configure ${CONFOPTS} --prefix="${BUILTDIR}" --libdir="lib" --cross-compile-prefix="${X86_MINGW_PREFIX}"
	make depend || exit 1
	make ${MAKEOPTS} && make install_sw || exit 1

	if [ "x${TYPE}" = "xshared" ]; then
		cp libeay32.dll "${BUILTDIR}/bin/"
		cp ssleay32.dll "${BUILTDIR}/bin/"
	fi

	unset CONFOPTS

	return 0
}

if [ ! -z "${OPENSSL_ARCHIVE}" ]; then
	echo "Building openssl."
	if target_scheduled static; then build_openssl static || exit 1; fi
	if target_scheduled shared; then build_openssl shared || exit 1; fi
fi

# Windows Xp and Vista don't support TLS 1.2 which is required since 1.9.2018.
# https://www.datoveschranky.info/-/konec-podpory-protokolu-tls-ve-verzich-1-0-a-1-1-
USE_WINSSL="yes"
USE_OPENSSL_LOCAL_CA_STORE="no"
LOCAL_CA_STORE_DIR="ssl/certs"
LOCAL_CA_STORE_FILE="ca-certificates.crt"


build_json_c () {
	local TYPE="$1"
	check_params "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${TYPE}")
	local BUILTDIR=$(builtdir_name "${TYPE}")

	local CROSS_COMPILER_ROOT="/usr/${X86_MINGV_HOST}"
	if [ ! -d "${CROSS_COMPILER_ROOT}" ]; then
		echo "Missing ${CROSS_COMPILER_ROOT}" >&2
		exit 1
	fi

	erase_and_decompress "${SRCDIR}" "${JSON_C_ARCHIVE}" "${WORKDIR}" curl
	cd "${WORKDIR}"/json-c*

	if [ "x${JSON_C_ARCHIVE_PATCHES}" != "x" ]; then
		# Apply patches.
		for f in ${JSON_C_ARCHIVE_PATCHES}; do
			local PATCHFILE="${PATCHDIR}/${f}"
			if [ ! -f "${PATCHFILE}" ]; then
				echo "Missing ${PATCHFILE}" >&2
				exit 1
			fi
			cp "${PATCHFILE}" ./
			echo "Applying ${f}"
			patch -p1 < ${f}
			unset PATCHFILE
		done
	fi

	# It is funny that even cmake advocates admit that it can quickly end up in a pile of garbage:
	# https://www.reddit.com/r/cpp/comments/qum4sq/whats_the_hate_for_cmake_all_about_is_cmake
	# https://stackoverflow.com/beta/discussions/77979031/why-do-people-hate-cmake-and-why-hasnt-a-better-cmake-taken-its-place
	# https://news.ycombinator.com/item?id=34964152
	# ad CMP0048:
	# https://stackoverflow.com/questions/37582508/silence-cmp0048-warnings-in-vendored-projects

	cmake \
	    -DCMAKE_POLICY_DEFAULT_CMP0048=NEW \
	    -DCMAKE_INSTALL_PREFIX="${BUILTDIR}" \
	    -DCMAKE_BUILD_TYPE=Release \
	    -DBUILD_SHARED_LIBS=ON \
	    -DDISABLE_WERROR=ON \
	    -DDISABLE_EXTRA_LIBS=ON \
	    -DBUILD_TESTING=OFF \
	    -DCMAKE_SYSTEM_NAME=Windows \
	    -DCMAKE_C_COMPILER="${X86_MINGW_CC}" \
	    -DCMAKE_CXX_COMPILER="${X86_MINGW_CXX}" \
	    -DCMAKE_FIND_ROOT_PATH="/usr/${CROSS_COMPILER_ROOT}" \
	    -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
	    -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
	    -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY
	make ${MAKEOPTS} && make install || exit 1
}

if [ ! -z "${JSON_C_ARCHIVE}" ]; then
	echo "Building json-c."
	if target_scheduled static; then build_json_c static || exit 1; fi
	if target_scheduled shared; then build_json_c shared || exit 1; fi
fi


build_libcurl () {
	local TYPE="$1"
	check_params "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${TYPE}")
	local BUILTDIR=$(builtdir_name "${TYPE}")

	erase_and_decompress "${SRCDIR}" "${LIBCURL_ARCHIVE}" "${WORKDIR}" curl
	cd "${WORKDIR}"/curl*

	local CONFOPTS=""
	CONFOPTS="${CONFOPTS} --prefix=${BUILTDIR}"
	if [ "x${TYPE}" = "xstatic" ]; then
		CONFOPTS="${CONFOPTS} --disable-shared"
	fi
	if [ "x${TYPE}" = "xshared" ]; then
		CONFOPTS="${CONFOPTS} --disable-static"
	fi
	#CONFOPTS="${CONFOPTS} --enable-crypto-auth" # ?
	CONFOPTS="${CONFOPTS} --enable-http"
	CONFOPTS="${CONFOPTS} --enable-ipv6"
	CONFOPTS="${CONFOPTS} --enable-proxy"
	CONFOPTS="${CONFOPTS} --disable-file"
	CONFOPTS="${CONFOPTS} --disable-ftp"
	CONFOPTS="${CONFOPTS} --disable-gopher"
	CONFOPTS="${CONFOPTS} --disable-imap"
	CONFOPTS="${CONFOPTS} --disable-ldap"
	CONFOPTS="${CONFOPTS} --disable-ldaps"
	CONFOPTS="${CONFOPTS} --disable-manual"
	CONFOPTS="${CONFOPTS} --disable-pop3"
	CONFOPTS="${CONFOPTS} --disable-rtsp"
	CONFOPTS="${CONFOPTS} --disable-smb"
	CONFOPTS="${CONFOPTS} --disable-smtp"
	#CONFOPTS="${CONFOPTS} --disable-sspi"
	CONFOPTS="${CONFOPTS} --disable-telnet"
	CONFOPTS="${CONFOPTS} --disable-tftp"
	CONFOPTS="${CONFOPTS} --without-axtls"
	CONFOPTS="${CONFOPTS} --without-cyassl"
	if [ "x${USE_OPENSSL_LOCAL_CA_STORE}" = "xno" ]; then
		CONFOPTS="${CONFOPTS} --without-ssl" # without OpenSSL
	else
		CONFOPTS="${CONFOPTS} --with-ssl=${BUILTDIR}"
		CONFOPTS="${CONFOPTS} --with-ca-path=${LOCAL_CA_STORE_DIR}"
		CONFOPTS="${CONFOPTS} --with-ca-bundle=${LOCAL_CA_STORE_DIR}/${LOCAL_CA_STORE_FILE}"
	fi
	CONFOPTS="${CONFOPTS} --without-wolfssl" # since curl-7.60.0
	CONFOPTS="${CONFOPTS} --without-zsh-functions-dir"
	#CONFOPTS="${CONFOPTS} --with-ca-fallback" # ?
	if [ "x${USE_WINSSL}" = "xyes" ]; then
		CONFOPTS="${CONFOPTS} --with-winssl"
	else
		CONFOPTS="${CONFOPTS} --without-winssl"
	fi

	./configure ${CONFOPTS} --host="${X86_MINGV_HOST}" \
	    CPPFLAGS="-DWINVER=${WIN_VER}"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS

	return 0
}

if [ ! -z "${LIBCURL_ARCHIVE}" ]; then
	echo "Building libcurl."
	if target_scheduled static; then build_libcurl static || exit 1; fi
	if target_scheduled shared; then build_libcurl shared || exit 1; fi
fi


build_libdatovka () {
	local TYPE="$1"
	check_params "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${TYPE}")
	local BUILTDIR=$(builtdir_name "${TYPE}")

	if [ ! -z "${LIBDATOVKA_ARCHIVE}" ]; then
		erase_and_decompress "${SRCDIR}" "${LIBDATOVKA_ARCHIVE}" "${WORKDIR}" libdatovka
		cd "${WORKDIR}"/libdatovka*

		if [ "x${LIBDATOVKA_ARCHIVE_PATCHES}" != "x" ]; then
			# Apply patches.
			for f in ${LIBDATOVKA_ARCHIVE_PATCHES}; do
				local PATCHFILE="${PATCHDIR}/${f}"
				if [ ! -f "${PATCHFILE}" ]; then
					echo "Missing ${PATCHFILE}" >&2
					exit 1
				fi
				cp "${PATCHFILE}" ./
				echo "Applying ${f}"
				patch -p1 < ${f}
				unset PATCHFILE
			done
		fi
	elif [ ! -z "${LIBDATOVKA_GIT}" ]; then
		# libdatovka with OpenSSL back-end
		rm -rf "${WORKDIR}"/libdatovka*
		cd "${WORKDIR}"
		if [ -z "${LIBDATOVKA_BRANCH}" ]; then
			LIBDATOVKA_BRANCH="--"
		fi
		download_repo_branch_head "${LIBDATOVKA_GIT}" "${LIBDATOVKA_BRANCH}" libdatovka-git
		cd "${WORKDIR}"/libdatovka*
	else
		echo "Cannot prepare libdatovka sources." >&2
		exit 1
	fi

	local CONFOPTS=""
	CONFOPTS="${CONFOPTS} --prefix=${BUILTDIR}"
	if [ "x${TYPE}" = "xstatic" ]; then
		CONFOPTS="${CONFOPTS} --disable-shared"
	fi
	if [ "x${TYPE}" = "xshared" ]; then
		CONFOPTS="${CONFOPTS} --disable-static"
	fi
	CONFOPTS="${CONFOPTS} --enable-debug"
	CONFOPTS="${CONFOPTS} --enable-openssl-backend"
	CONFOPTS="${CONFOPTS} --disable-doc" # libdatovka-0.0 requires xsltproc to build documentation
	CONFOPTS="${CONFOPTS} --disable-fatalwarnings"
	CONFOPTS="${CONFOPTS} --with-xml-prefix=${BUILTDIR}"
	CONFOPTS="${CONFOPTS} --with-libcurl=${BUILTDIR}"
	CONFOPTS="${CONFOPTS} --with-libiconv-prefix=${BUILTDIR}"

	local LINTL=""
	local NLS="--disable-nls"
	if [ ! -z "${GETTEXT_ARCHIVE}" ]; then
		LINTL="-lintl"
		NLS=""
	fi
	CONFOPTS="${CONFOPTS} ${NLS}"

	local DEFINES=""
	local LINKER=""
	if [ "x${TYPE}" = "xstatic" ]; then
		DEFINES="${DEFINES} -DLIBXML_STATIC"
		LINKER="${LINKER} -mwindows"
	fi

	if [ -z "${LIBDATOVKA_ARCHIVE}" -a ! -z "${LIBDATOVKA_GIT}" ]; then
		cat configure.ac | sed -e 's/AC_FUNC_MALLOC//g' > nomalloc_configure.ac
		mv nomalloc_configure.ac configure.ac
		autoheader && libtoolize -c --install && aclocal -I m4 && automake --add-missing --copy && autoconf && echo "configure build ok"
	fi
	# Receiving undefined reference to `rpl_malloc' with i686-w64-mingw32.
	# The variable ac_cv_func_malloc_0_nonnull forces the malloc check to pass.
	PKG_CONFIG_PATH="${BUILTDIR}/lib/pkgconfig" \
	ac_cv_func_malloc_0_nonnull=yes \
	./configure ${CONFOPTS} --host="${X86_MINGV_HOST}" \
	    CPPFLAGS="-I${BUILTDIR}/include -I${BUILTDIR}/include/libxml2 ${DEFINES}" \
	    LDFLAGS="-L${BUILTDIR}/lib ${LINKER}"
	make ${MAKEOPTS} LDFLAGS=-no-undefined # MinGW linker requires the -no-undefined parameter.
#	if [ "x${TYPE}" = "xshared" ]; then
#		cd src
#		#i686-pc-mingw32-gcc -shared -O2 -g -std=c99 -Wall -o .libs/libdatovka.dll libdatovka_la-cdecode.o libdatovka_la-cencode.o libdatovka_la-datovka.o libdatovka_la-physxml.o libdatovka_la-utils.o libdatovka_la-validator.o libdatovka_la-crypto_openssl.o libdatovka_la-soap.o libdatovka_la-win32.o -L${BUILTDIR}/lib -lxml2 -liconv -lcurl -lexpat -lintl -lcrypto
#		#../libtool -v --tag=CC --mode=link i686-pc-mingw32-gcc  -g -O2 -g -std=c99 -Wall -version-info 8:0:3 -L${BUILTDIR}/lib -lxml2 -lz -L${BUILTDIR}/lib -liconv -L${BUILTDIR}/lib -lcurl -lwldap32 -lz -lws2_32 -lexpat -L${BUILTDIR}/lib -lintl -L${BUILTDIR}/lib -liconv -R${BUILTDIR}/lib -L${BUILTDIR}/lib -o libdatovka.la -rpath ${BUILTDIR}/lib libdatovka_la-cdecode.lo libdatovka_la-cencode.lo libdatovka_la-datovka.lo libdatovka_la-physxml.lo libdatovka_la-utils.lo libdatovka_la-validator.lo libdatovka_la-crypto_openssl.lo libdatovka_la-soap.lo libdatovka_la-win32.lo -L${BUILTDIR}/bin -leay32 -no-undefined
#		../libtool -v --tag=CC --mode=link ${X86_MINGW_CC} -g -O2 -g -std=c99 -Wall -version-info 8:0:3 -L${BUILTDIR}/lib -lxml2 -lz -L${BUILTDIR}/lib -liconv -L${BUILTDIR}/lib -lcurl -lwldap32 -lz -lws2_32 -lexpat -L${BUILTDIR}/lib ${LINTL} -L${BUILTDIR}/lib -liconv -R${BUILTDIR}/lib -L${BUILTDIR}/lib -o libdatovka.la -rpath ${BUILTDIR}/lib libdatovka_la-cdecode.lo libdatovka_la-cencode.lo libdatovka_la-datovka.lo libdatovka_la-physxml.lo libdatovka_la-utils.lo libdatovka_la-validator.lo libdatovka_la-crypto_openssl.lo libdatovka_la-soap.lo libdatovka_la-win32.lo -L${BUILTDIR}/bin -leay32 -no-undefined
#		cd ..
#	fi
	make install || exit 1

	unset CONFOPTS
	unset DEFINES
	unset LINKER

	return 0
}

if [ ! -z "${LIBDATOVKA_ARCHIVE}" -a ! -z "${LIBDATOVKA_GIT}" ]; then
	echo "Select libdatovka archive or git repository." >&2
	exit 1
elif [ ! -z "${LIBDATOVKA_ARCHIVE}" -o ! -z "${LIBDATOVKA_GIT}" ]; then
	echo "Building libdatovka."
	if target_scheduled static; then build_libdatovka static || exit 1; fi
	if target_scheduled shared; then build_libdatovka shared || exit 1; fi
fi


# Create copy of build directory.
builddir_copy () {
	local TYPE="$1"
	local ARCH="$2"
	check_params "${TYPE}" || exit 1
	local BUILTDIR=$(builtdir_name "${TYPE}")

	local TGT_BUILT_DIR="${TYPE}_built_${ARCH}"

	rm -r "${LIB_ROOT}/${TGT_BUILT_DIR}"
	cp -r "${BUILTDIR}" "${LIB_ROOT}/${TGT_BUILT_DIR}"
	cd "${LIB_ROOT}"
	local DATE=$(date -u '+%Y%m%d_%H%M%S')
	tar -czf "${TGT_BUILT_DIR}_${DATE}.tar.gz" "${TGT_BUILT_DIR}/"
}

# Copy build directory.
if target_scheduled static; then builddir_copy static "${ARCH_NAME}"; fi
if target_scheduled shared; then builddir_copy shared "${ARCH_NAME}"; fi
