#!/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-s SDK_VERSION_NUMBER, --sdk SDK_VERSION_NUMBER\n\t\tSupply SDK version name (e.g. 10.7).\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"
USAGE="${USAGE}\t--arm64\n\t\tCompile for the arm64 architecture.\n"

cd "${SRC_ROOT}"

SDK_VER=""

ARCH_NAME=""
ARCH_I386="i386"
ARCH_X86_64="x86_64"
ARCH_ARM64="arm64"

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 sdk: -l i386 -l x86_64 -l arm64 -u -o hs: -- "$@")
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
		;;
	-s|--sdk)
		if [ "x${SDK_VER}" = "x" ]; then
			SDK_VER=$(echo "${PARAM}" | grep '^[0-9][0-9]*\.[0-9][0-9]*$')
			if [ "x${SDK_VER}" = "x" ]; then
				SDK_VER=$(echo "${PARAM}" | grep '^[0-9][0-9]*$')
			fi
			if [ "x${SDK_VER}" = "x" ]; then
				echo "Wrong -s option parameter '${PARAM}'." >&2
				exit 1
			fi
		else
			echo "Option -s already set." >&2
			exit 1
		fi
		shift
		;;
	--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
		;;
	--arm64)
		if [ "x${ARCH_NAME}" = "x" ]; then
			ARCH_NAME="${ARCH_ARM64}"
		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

# Test whether SDK version is really set.
if [ "x${SDK_VER}" = "x" ]; then
	echo "Option -s was not set. Using default SDK." >&2
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 "macos32_x86"
elif [ "x${ARCH_NAME}" = "x${ARCH_X86_64}" ]; then
	adjust_sources "macos64_x86_64"
elif [ "x${ARCH_NAME}" = "x${ARCH_ARM64}" ]; then
	adjust_sources "macos64_arm64"
else
	echo "Unknown architecture." >&2
	exit 1
fi

adjust_sources "macos"

OSX_MIN_VER=10.7
MAKEOPTS="-j 2"

SDKROOT="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs"
ISYSROOT="${SDKROOT}/MacOSX${SDK_VER}.sdk"

if [ ! -d "${ISYSROOT}" ]; then
	echo "Directory '${ISYSROOT}' does not exist." >&2
	if [ "x${SDK_VER}" = "x" ]; then
		echo "Cannot find SDK root '${ISYSROOT}'." >&2
	else
		echo "Cannot find SDK root '${ISYSROOT}' for version '${SDK_VER}'." >&2
	fi
	exit 1
fi

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}"

SRCDIR="${LIB_ROOT}/srcs"
PATCHDIR="${SRC_ROOT}/scripts/patches"
WORKDIR_PREFIX="${LIB_ROOT}/work_macos"
BUILTDIR_PREFIX="${LIB_ROOT}/built_macos"
if [ "x${SDK_VER}" != "x" ]; then
	WORKDIR_PREFIX="${LIB_ROOT}/work_macos_sdk${SDK_VER}"
	BUILTDIR_PREFIX="${LIB_ROOT}/built_macos_sdk${SDK_VER}"
fi

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

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

# Specifies which targets to build.
TARGETS=""
if [ "x${ARCH_NAME}" = "x${ARCH_I386}" ]; then
	TARGETS="${TARGETS} i386_static"
	TARGETS="${TARGETS} i386_shared"
elif [ "x${ARCH_NAME}" = "x${ARCH_X86_64}" ]; then
	TARGETS="${TARGETS} x86_64_static"
	TARGETS="${TARGETS} x86_64_shared"
elif [ "x${ARCH_NAME}" = "x${ARCH_ARM64}" ]; then
	TARGETS="${TARGETS} arm64_static"
	TARGETS="${TARGETS} arm64_shared"
fi

# Return 0 if targets are OK.
check_params () {
	local ARCH="$1"
	local TYPE="$2"
	if [ "x${ARCH}" != "xi386" -a "x${ARCH}" != "xx86_64" -a "x${ARCH}" != "xarm64" ]; then
		echo "Unknown architecture '${ARCH}'." >&2
		return 1
	fi
	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 ARCH="$1"
	local TYPE="$2"
	check_params "${ARCH}" "${TYPE}" || return 1
	local RES=""
	RES=$(echo "${TARGETS}" | grep "${ARCH}" | grep "${TYPE}")
	if [ "x${RES}" != "x" ]; then
		return 0
	else
		return 1
	fi
}

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

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

add_suffix_to_dir () {
	local DIR="$1"
	local SUFFIX="$2"
	if [ -d "${DIR}" ]; then
		mv "${DIR}" "${DIR}${SUFFIX}"
	fi
}

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

TIME_SUFFIX=$(date '+_bak_%Y%m%d_%H%M%S')

# Back up already existent built directories.
target_scheduled i386 static && add_suffix_to_dir $(builtdir_name i386 static) "${TIME_SUFFIX}"
target_scheduled i386 shared && add_suffix_to_dir $(builtdir_name i386 shared) "${TIME_SUFFIX}"
target_scheduled x86_64 static && add_suffix_to_dir $(builtdir_name x86_64 static) "${TIME_SUFFIX}"
target_scheduled x86_64 shared && add_suffix_to_dir $(builtdir_name x86_64 shared) "${TIME_SUFFIX}"
target_scheduled arm64 static && add_suffix_to_dir $(builtdir_name arm64 static) "${TIME_SUFFIX}"
target_scheduled arm64 shared && add_suffix_to_dir $(builtdir_name arm64 shared) "${TIME_SUFFIX}"

# Create missing directories.
target_scheduled i386 static && ensure_dir_presence $(workdir_name i386 static)
target_scheduled i386 static && ensure_dir_presence $(builtdir_name i386 static)
target_scheduled i386 shared && ensure_dir_presence $(workdir_name i386 shared)
target_scheduled i386 shared && ensure_dir_presence $(builtdir_name i386 shared)
target_scheduled x86_64 static && ensure_dir_presence $(workdir_name x86_64 static)
target_scheduled x86_64 static && ensure_dir_presence $(builtdir_name x86_64 static)
target_scheduled x86_64 shared && ensure_dir_presence $(workdir_name x86_64 shared)
target_scheduled x86_64 shared && ensure_dir_presence $(builtdir_name x86_64 shared)
target_scheduled arm64 static && ensure_dir_presence $(workdir_name arm64 static)
target_scheduled arm64 static && ensure_dir_presence $(builtdir_name arm64 static)
target_scheduled arm64 shared && ensure_dir_presence $(workdir_name arm64 shared)
target_scheduled arm64 shared && ensure_dir_presence $(builtdir_name arm64 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 is already available in the system.
USE_SYSTEM_CURL="yes"
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"

# lipo -info
# otool -L

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

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

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

	CFLAGS="-mmacosx-version-min=${OSX_MIN_VER} -arch ${ARCH}" LDFLAGS="-mmacosx-version-min=${OSX_MIN_VER}" ./configure ${CONFOPTS} --archs="-arch ${ARCH}"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS

	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 i386 static; then build_zlib i386 static || exit 1; fi
	if target_scheduled i386 shared; then build_zlib i386 shared || exit 1; fi
	if target_scheduled x86_64 static; then build_zlib x86_64 static || exit 1; fi
	if target_scheduled x86_64 shared; then build_zlib x86_64 shared || exit 1; fi
	if target_scheduled arm64 static; then build_zlib arm64 static || exit 1; fi
	if target_scheduled arm64 shared; then build_zlib arm64 shared || exit 1; fi
fi


build_expat () {
	local ARCH="$1"
	local TYPE="$2"
	check_params "${ARCH}" "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${ARCH}" "${TYPE}")
	local BUILTDIR=$(builtdir_name "${ARCH}" "${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} \
	    CFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}" \
	    CXXFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}" \
	    LDFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS

	return 0
}

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


build_libtool () {
	local ARCH="$1"
	local TYPE="$2"
	check_params "${ARCH}" "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${ARCH}" "${TYPE}")
	local BUILTDIR=$(builtdir_name "${ARCH}" "${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} \
	    CFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}" \
	    CXXFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}" \
	    LDFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS

	return 0
}

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


build_libiconv () {
	local ARCH="$1"
	local TYPE="$2"
	check_params "${ARCH}" "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${ARCH}" "${TYPE}")
	local BUILTDIR=$(builtdir_name "${ARCH}" "${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} \
	    CFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}" \
	    CXXFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}" \
	    LDFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS

	return 0
}

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


build_libxml2 () {
	local ARCH="$1"
	local TYPE="$2"
	check_params "${ARCH}" "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${ARCH}" "${TYPE}")
	local BUILTDIR=$(builtdir_name "${ARCH}" "${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} \
	    CFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}" \
	    CXXFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}" \
	    LDFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS

	return 0
}

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


build_gettext () {
	local ARCH="$1"
	local TYPE="$2"
	check_params "${ARCH}" "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${ARCH}" "${TYPE}")
	local BUILTDIR=$(builtdir_name "${ARCH}" "${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} --disable-java"

	./configure ${CONFOPTS} \
	    CFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}" \
	    CXXFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}" \
	    CPPFLAGS="-I${BUILTDIR}/include" \
	    LDFLAGS="-L${BUILTDIR}/lib -arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS

	return 0
}

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


build_openssl () {
	local ARCH="$1"
	local TYPE="$2"
	check_params "${ARCH}" "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${ARCH}" "${TYPE}")
	local BUILTDIR=$(builtdir_name "${ARCH}" "${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"
	if [ "x${ARCH}" = "xi386" ]; then
		CONFOPTS="${CONFOPTS} darwin-i386-cc"
	fi
	if [ "x${ARCH}" = "xx86_64" ]; then
		CONFOPTS="${CONFOPTS} darwin64-x86_64-cc"
	fi
	if [ "x${ARCH}" = "xarm64" ]; then
		CONFOPTS="${CONFOPTS} darwin64-arm64-cc"
	fi
	CONFOPTS="${CONFOPTS} enable-static-engine"
	if [ "x${TYPE}" = "xstatic" ]; then
		CONFOPTS="${CONFOPTS} no-shared"
	fi
	if [ "x${TYPE}" = "xshared" ]; then
		CONFOPTS="${CONFOPTS} shared"
	fi
	local OPENSSL_1_0_2=$(echo ${OPENSSL_ARCHIVE} | grep '1\.0\.2')
	if [ "x${OPENSSL_1_0_2}" != "x" ]; then
		CONFOPTS="${CONFOPTS} no-krb5" # OpenSSL-1.1.x does not know this parameter.
	fi

	./Configure ${CONFOPTS} --prefix="${BUILTDIR}" --libdir="lib"
	# Patch Makefile
	sed -ie "s/^CFLAG= -/CFLAG=  -mmacosx-version-min=${OSX_MIN_VER} -/" Makefile
	make depend || exit 1
	make ${MAKEOPTS} && make install_sw || exit 1

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

	unset CONFOPTS

	return 0
}

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


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

	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

	local BUILD_SHARED="ON"
	local BUILD_STATIC="ON"
	if [ "x${TYPE}" = "xstatic" ]; then
		BUILD_SHARED="OFF"
		BUILD_STATIC="ON"
	fi
	if [ "x${TYPE}" = "xshared" ]; then
		BUILD_SHARED="ON"
		BUILD_STATIC="OFF"
	fi

	local BDIR="build"

	cmake \
	    -S . -B "${BDIR}" \
	    -DCMAKE_INSTALL_PREFIX="${BUILTDIR}" \
	    -DCMAKE_BUILD_TYPE=Release \
	    -DBUILD_SHARED_LIBS=${BUILD_SHARED} \
	    -DBUILD_STATIC_LIBS=${BUILD_STATIC} \
	    -DBUILD_APPS=OFF \
	    -DDISABLE_WERROR=ON \
	    -DDISABLE_EXTRA_LIBS=ON \
	    -DBUILD_TESTING=OFF \
	    -DCMAKE_SYSTEM_NAME=Darwin \
	    -DCMAKE_OSX_ARCHITECTURES:STRING="${ARCH}"
	make ${MAKEOPTS} -C "${BDIR}" && make -C "${BDIR}" install || exit 1
}

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


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

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

	local CONFOPTS=""
	CONFOPTS="${CONFOPTS} --prefix=${BUILTDIR}"
	# Leave shared version as this is required to configure libdatovka.
	#if [ "x${TYPE}" = "xstatic" ]; then
	#	CONFOPTS="${CONFOPTS} --disable-shared"
	#fi
	if [ "x${TYPE}" = "xshared" ]; then
		CONFOPTS="${CONFOPTS} --disable-static"
	fi
	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-zsh-functions-dir"
	CONFOPTS="${CONFOPTS} --with-darwinssl"

	# Recent libcurl may require OSX_MIN_VER 10.8 or later.

	./configure ${CONFOPTS} \
	    CFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER} -isysroot ${ISYSROOT}" \
	    CXXFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER} -isysroot ${ISYSROOT}" \
	    LDFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER} -isysroot ${ISYSROOT}"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS

	return 0
}

if [ "x${USE_SYSTEM_CURL}" != "xyes" ] && [ ! -z "${LIBCURL_ARCHIVE}" ]; then
	echo "Building libcurl."
	if target_scheduled i386 static; then build_libcurl i386 static || exit 1; fi
	if target_scheduled i386 shared; then build_libcurl i386 shared || exit 1; fi
	if target_scheduled x86_64 static; then build_libcurl x86_64 static || exit 1; fi
	if target_scheduled x86_64 shared; then build_libcurl x86_64 shared || exit 1; fi
	if target_scheduled arm64 static; then build_libcurl arm64 static || exit 1; fi
	if target_scheduled arm64 shared; then build_libcurl arm64 shared || exit 1; fi
fi


build_libdatovka () {
	local ARCH="$1"
	local TYPE="$2"
	check_params "${ARCH}" "${TYPE}" || exit 1
	local WORKDIR=$(workdir_name "${ARCH}" "${TYPE}")
	local BUILTDIR=$(builtdir_name "${ARCH}" "${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
		git clone "${LIBDATOVKA_GIT}" 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 NLS="--disable-nls"
	if [ ! -z "${GETTEXT_ARCHIVE}" ]; then
		NLS=""
	fi
	CONFOPTS="${CONFOPTS} ${NLS}"

	if [ -z "${LIBDATOVKA_ARCHIVE}" -a ! -z "${LIBDATOVKA_GIT}" ]; then
		autoheader && glibtoolize -c --install && aclocal -I m4 && automake --add-missing --copy && autoconf && echo "configure build ok"
	fi
	PKG_CONFIG_PATH="${BUILTDIR}/lib/pkgconfig" \
	./configure ${CONFOPTS} \
	    CFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}" \
	    CXXFLAGS="-arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}" \
	    CPPFLAGS="-I${BUILTDIR}/include -I${BUILTDIR}/include/libxml2" \
	    LDFLAGS="-L${BUILTDIR}/lib -arch ${ARCH} -mmacosx-version-min=${OSX_MIN_VER}"
	make ${MAKEOPTS} && make install || exit 1

	unset CONFOPTS

	if [ "x${TYPE}" = "xstatic" -a -f "${BUILTDIR}/lib/libcurl.dylib" ]; then
		mv "${BUILTDIR}/lib/libcurl.dylib" "${BUILTDIR}/lib/libcurl.dylib_x"
	fi

	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 i386 static; then build_libdatovka i386 static || exit 1; fi
	if target_scheduled i386 shared; then build_libdatovka i386 shared || exit 1; fi
	if target_scheduled x86_64 static; then build_libdatovka x86_64 static || exit 1; fi
	if target_scheduled x86_64 shared; then build_libdatovka x86_64 shared || exit 1; fi
	if target_scheduled arm64 static; then build_libdatovka arm64 static || exit 1; fi
	if target_scheduled arm64 shared; then build_libdatovka arm64 shared || exit 1; fi
fi

replace_dylib_rpath() {
	local ARCH="$1"
	local TYPE="$2"
	check_params "${ARCH}" "${TYPE}" || exit 1
	local BUILTDIR=$(builtdir_name "${ARCH}" "${TYPE}")
	local LIBDIR="${BUILTDIR}/lib"
	local RPATH_SCRIPT="../../../scripts/macos_dylib_replace_rpath.sh"

	if [ ! -d "${LIBDIR}" ]; then
		echo "Directory '${LIBDIR}' doesn't exist."
		return 1
	fi

	pushd "${LIBDIR}" >/dev/null

	if [ ! -e "${RPATH_SCRIPT}" ]; then
		echo "Missing script '${RPATH_SCRIPT}'."
		popd >/dev/null
		return 1
	fi

	${RPATH_SCRIPT}

	popd >/dev/null

	return 0
}

if [ true ]; then
	echo "Replacing rpath occurences."
	if target_scheduled i386 shared; then replace_dylib_rpath i386 shared || exit 1; fi
	if target_scheduled x86_64 shared; then replace_dylib_rpath x86_64 shared || exit 1; fi
	if target_scheduled arm64 shared; then replace_dylib_rpath arm64 shared || exit 1; fi
fi
