#!/bin/sh -e
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

# next steps:
# try running this, figure out what to do with the vars in the generated files
# in the bottom

# cd into this script’s directory
rootdir="$(cd "${0%/*}" 2>/dev/null; echo "$PWD")"
basename=`basename $0`

PACKAGE_AUTHOR_NAME="The Apache Software Foundation"

REBAR3_BRANCH="3.21.0"
ERLFMT_VERSION="v1.3.0"

# TEST=0
WITH_PROPER="true"
WITH_FAUXTON=1
WITH_DOCS=1
WITH_NOUVEAU="false"
WITH_CLOUSEAU=0
ERLANG_MD5="false"
SKIP_DEPS=0

run_erlang() {
    erl -noshell -eval "$1" -eval "halt()."
}

COUCHDB_USER="$(whoami 2>/dev/null || echo couchdb)"
SM_VSN=${SM_VSN:-"91"}
CLOUSEAU_MTH=${CLOUSEAU_MTH:-"dist"}
CLOUSEAU_URI=${CLOUSEAU_URI:-"https://github.com/cloudant-labs/clouseau/releases/download/%s/clouseau-%s-dist.zip"}
CLOUSEAU_VSN=${CLOUSEAU_VSN:-"2.22.0"}
CLOUSEAU_DIR="$(pwd)"/clouseau
ARCH="$(uname -m)"
ERLANG_VER="$(run_erlang 'io:put_chars(erlang:system_info(otp_release)).')"
ERLANG_OS="$(run_erlang 'case os:type() of {OS, _} -> io:format("~s~n", [OS]) end.')"

. ${rootdir}/version.mk
COUCHDB_VERSION=${vsn_major}.${vsn_minor}.${vsn_patch}

display_help () {
    cat << EOF
Usage: $basename [OPTION]

The $basename command is responsible for generating the build
system for Apache CouchDB.

Options:

  -h | --help                 display a short help message and exit
  -u | --user USER            set the username to run as (defaults to $COUCHDB_USER)
  --disable-fauxton           do not build Fauxton
  --disable-docs              do not build any documentation or manpages
  --enable-nouveau            enable the new experimental search module
  --enable-clouseau           enable the Clouseau search module
  --erlang-md5                use erlang for md5 hash operations
  --dev                       alias for --disable-docs --disable-fauxton
  --spidermonkey-version VSN  specify the version of SpiderMonkey to use (defaults to $SM_VSN)
  --clouseau-method MTH       specify the method for Clouseau to deploy: git or dist (defaults to $CLOUSEAU_MTH)
  --clouseau-uri URI          specify the location for retrieving Clouseau (defaults $(printf "$CLOUSEAU_URI" "$CLOUSEAU_VSN" "$CLOUSEAU_VSN"))
  --clouseau-version VSN      specify the version (tag/branch for git) of Clouseau to use (defaults to $CLOUSEAU_VSN)
  --skip-deps                 do not update erlang dependencies
  --rebar=PATH                use rebar by specified path (version >=2.6.0 && <3.0 required)
  --rebar3=PATH               use rebar3 by specified path
  --erlfmt=PATH               use erlfmt by specified path
EOF
}

parse_opts() {
    while :; do
        case $1 in
            -h|--help)
                display_help
                exit
                ;;

            --without-proper)
                WITH_PROPER="false"
                shift
                continue
                ;;

            --disable-fauxton)
                WITH_FAUXTON=0
                shift
                continue
                ;;

            --disable-docs)
                WITH_DOCS=0
                shift
                continue
                ;;

            --enable-nouveau)
                WITH_NOUVEAU="true"
                shift
                continue
                ;;

	    --enable-clouseau)
		if [ "${ERLANG_VER}" -gt 25 ]; then
		    echo "Warning: Clouseau is not working with OTP 26 or later at the moment, therefore it is not configured.  Continue in 5 seconds..."
		    sleep 5
		else
		    WITH_CLOUSEAU=1
		fi
		shift
		continue
		;;

            --erlang-md5)
                ERLANG_MD5="true"
                shift
                continue
                ;;

            --dev)
                WITH_DOCS=0
                WITH_FAUXTON=0
                shift
                continue
                ;;

            --dev-with-nouveau)
                WITH_DOCS=0
                WITH_FAUXTON=0
                WITH_NOUVEAU="true"
                shift
                continue
                ;;

            --skip-deps)
                SKIP_DEPS=1
                shift
                continue
                ;;

            --rebar)
                if [ -x "$2" ]; then
                    version=`$2 --version 2> /dev/null | grep -o "2\.[6-9]\.[0-9]"`
                    if [ $? -ne 0 ]; then
                        printf 'Rebar >=2.6.0 and <3.0.0 required' >&2
                        exit 1
                    fi
                    eval REBAR=$2
                    shift 2
                    continue
                else
                    printf 'ERROR: "--rebar" requires valid path to executable.\n' >&2
                    exit 1
                fi
                ;;

            --rebar3)
                if [ -x "$2" ]; then
                    eval REBAR3=$2
                    shift 2
                    continue
                else
                    printf 'ERROR: "--rebar3" requires valid path to executable.\n' >&2
                    exit 1
                fi
                ;;

            --erlfmt)
                if [ -x "$2" ]; then
                    eval ERLFMT=$2
                    shift 2
                    continue
                else
                    printf 'ERROR: "--erlfmt" requires valid path to executable.\n' >&2
                    exit 1
                fi
                ;;

            --user|-u)
                if [ -n "$2" ]; then
                    eval COUCHDB_USER=$2
                    shift 2
                    continue
                else
                    printf 'ERROR: "--user" requires a non-empty argument.\n' >&2
                    exit 1
                fi
                ;;
            --user=?*)
                eval COUCHDB_USER=${1#*=}
                ;;
            --user=)
                printf 'ERROR: "--user" requires a non-empty argument.\n' >&2
                exit 1
                ;;

            --spidermonkey-version)
                if [ -n "$2" ]; then
                    eval SM_VSN=$2
                    shift 2
                    continue
                else
                    printf 'ERROR: "--spidermonkey-version" requires a non-empty argument.\n' >&2
                    exit 1
                fi
                ;;
            --spidermonkey-version=?*)
                eval SM_VSN=${1#*=}
                ;;
            --spidermonkey-version=)
                printf 'ERROR: "--spidermonkey-version" requires a non-empty argument.\n' >&2
                exit 1
                ;;

	    --clouseau-version)
		if [ -n "$2" ]; then
		    eval CLOUSEAU_VSN=$2
		    shift 2
		    continue
		else
		    printf 'ERROR: "--clouseau-version" requires a non-empty argument.\n' >&2
		    exit 1
		fi
		;;
	    --clouseau-version=?*)
		eval CLOUSEAU_VSN=${1#*=}
		;;
	    --clouseau-version=)
	        printf 'ERROR: "--clouseau-version" requires a non-empty argument.\n' >&2
	        exit 1
	        ;;

	    --clouseau-method)
		if [ -n "$2" ]; then
		    eval CLOUSEAU_MTH=$2
		    shift 2
		    continue
		else
		    printf 'ERROR: "--clouseau-method" requires a non-empty argument.\n' >&2
		    exit 1
		fi
		;;
	    --clouseau-method=?*)
		eval CLOUSEAU_MTH=${1#*=}
		;;
	    --clouseau-method=)
	        printf 'ERROR: "--clouseau-method" requires a non-empty argument.\n' >&2
	        exit 1
	        ;;

	    --clouseau-uri)
		if [ -n "$2" ]; then
		    eval CLOUSEAU_URI=$2
		    shift 2
		    continue
		else
		    printf 'ERROR: "--clouseau-uri" requires a non-empty argument.\n' >&2
		    exit 1
		fi
		;;
	    --clouseau-uri=?*)
		eval CLOUSEAU_URI=${1#*=}
		;;
	    --clouseau-uri=)
	        printf 'ERROR: "--clouseau-uri" requires a non-empty argument.\n' >&2
	        exit 1
	        ;;

            --) # End of options
                shift
                break
                ;;
            -?*)
                echo "WARNING: Unknown option '$1', ignoring" >&2
                shift
                ;;
            *) # Done
                break
        esac
        shift
    done
}

parse_opts $@

if [ "${ARCH}" = "aarch64" ] && [ "${SM_VSN}" = "60" ]; then
  echo "ERROR: SpiderMonkey 60 is known broken on ARM 64 (aarch64). Use another version instead."
  exit 1
fi

if [ "${ERLANG_OS}" = "unix" ]; then
    case "${SM_VSN}" in
        1.8.5)
            SM_HEADERS="js"
            ;;
        *)  SM_HEADERS="mozjs-${SM_VSN}"
            ;;
        esac

    # This list is taken from src/couch/rebar.config.script, please keep them in sync.
    if [ ! -d "/usr/include/${SM_HEADERS}" ] && \
        [ ! -d "/usr/local/include/${SM_HEADERS}" ] && \
        [ ! -d "/opt/homebrew/include/${SM_HEADERS}" ]; then
        echo "ERROR: SpiderMonkey ${SM_VSN} is not found. Please specify with --spidermonkey-version."
        exit 1
    fi
fi

# If we're in a release tarball and we don't have proper, then mark it as skipped
if [ ! -d .git ] && [ "$WITH_PROPER" = "true" ] && [ ! -d src/proper ]; then
    WITH_PROPER="false"
fi

echo "==> configuring couchdb in rel/couchdb.config"
cat > rel/couchdb.config << EOF
% Licensed under the Apache License, Version 2.0 (the "License"); you may not
% use this file except in compliance with the License. You may obtain a copy of
% the License at
%
%   http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
% License for the specific language governing permissions and limitations under
% the License.
%
% The contents of this file are auto-generated by configure
%
{package_author_name, "$PACKAGE_AUTHOR_NAME"}.
{prefix, "."}.
{data_dir, "./data"}.
{view_index_dir, "./data"}.
{nouveau_enable, "$WITH_NOUVEAU"}.
{nouveau_index_dir, "./data/nouveau"}.
{nouveau_url, "http://127.0.0.1:5987"}.
{nouveau_port, 5987}.
{nouveau_admin_port, 5988}.
{state_dir, "./data"}.
{log_file, "$LOG_FILE"}.
{fauxton_root, "./share/www"}.
{user, "$COUCHDB_USER"}.
{spidermonkey_version, "$SM_VSN"}.
{node_name, "-name couchdb@127.0.0.1"}.
{cluster_port, 5984}.
{backend_port, 5986}.
{prometheus_port, 17986}.
EOF

cat > install.mk << EOF
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
# The contents of this file are auto-generated by configure
#
package_author_name = $PACKAGE_AUTHOR_NAME

with_fauxton = $WITH_FAUXTON
with_docs = $WITH_DOCS
with_nouveau = $WITH_NOUVEAU
with_clouseau = $WITH_CLOUSEAU

user = $COUCHDB_USER
spidermonkey_version = $SM_VSN
EOF

cat > $rootdir/config.erl << EOF
{with_proper, $WITH_PROPER}.
{erlang_md5, $ERLANG_MD5}.
{spidermonkey_version, "$SM_VSN"}.
EOF

install_local_rebar() {
    if [ ! -x "${rootdir}/bin/rebar" ]; then
        if [ ! -d "${rootdir}/src/rebar" ]; then
            git clone --depth 1 https://github.com/apache/couchdb-rebar.git ${rootdir}/src/rebar
        fi
        make -C ${rootdir}/src/rebar
        mv ${rootdir}/src/rebar/rebar ${rootdir}/bin/rebar
        make -C ${rootdir}/src/rebar clean
    fi
}

install_local_rebar3() {
    if [ ! -x "${rootdir}/bin/rebar3" ]; then
        if [ ! -d "${rootdir}/src/rebar3" ]; then
            git clone --depth 1 --branch ${REBAR3_BRANCH} https://github.com/erlang/rebar3.git ${rootdir}/src/rebar3
        fi
        cd src/rebar3
        ./bootstrap
        mv ${rootdir}/src/rebar3/rebar3 ${rootdir}/bin/rebar3
        cd ../..
    fi
}

install_local_erlfmt() {
    if [ ! -x "${rootdir}/bin/erlfmt" ]; then
        if [ ! -d "${rootdir}/src/erlfmt" ]; then
            git clone --depth 1 --branch "${ERLFMT_VERSION}" https://github.com/WhatsApp/erlfmt.git ${rootdir}/src/erlfmt
        fi
        cd "${rootdir}"/src/erlfmt
        ${REBAR3} as release escriptize
        mv ${rootdir}/src/erlfmt/_build/release/bin/erlfmt ${rootdir}/bin/erlfmt
        ${REBAR3} clean
        cd ../..
    fi
}

check_local_clouseau_dir() {
    _dir="$1"

    if [ -e "$_dir" ]; then
	printf "ERROR: \"%s\" already exists.  Please remove or move it away first.\n" "$_dir" >&2
	exit 1
    fi
}

install_local_clouseau() {
    case "$CLOUSEAU_MTH" in
	dist)
	    _DIST_URL=$(printf "$CLOUSEAU_URI" "$CLOUSEAU_VSN" "$CLOUSEAU_VSN")
	    _MAVEN_BASE_URI=https://repo1.maven.org/maven2

	    _SLF4J_SIMPLE_VSN=${SLF4J_SIMPLE_VERSION:-1.7.36}
	    _SLF4J_SIMPLE_JAR=slf4j-simple-"$_SLF4J_SIMPLE_VSN".jar
	    _SLF4J_SIMPLE_URL="$_MAVEN_BASE_URI"/org/slf4j/slf4j-simple/"$_SLF4J_SIMPLE_VSN"/"$_SLF4J_SIMPLE_JAR"

	    check_local_clouseau_dir "$CLOUSEAU_DIR"
	    mkdir -p "$CLOUSEAU_DIR"

	    echo "Fetching Clouseau from $_DIST_URL..."
	    if ! curl -sSL --max-redirs 1 -o clouseau.zip "$_DIST_URL"; then
		printf "ERROR: %s could not be downloaded.\n" "$_DIST_URL" >&2
		exit 1
	    fi

	    if ! unzip -q -j clouseau.zip -d "$CLOUSEAU_DIR"; then
		printf "ERROR: Clouseau distribution package (clouseau.zip) could not be extracted.\n" >&2
		exit 1
	    fi

	    rm clouseau.zip

	    if ! curl -sSL --max-redirs 1 -o "$CLOUSEAU_DIR"/"$_SLF4J_SIMPLE_JAR" "$_SLF4J_SIMPLE_URL"; then
		printf "ERROR: %s could not be downloaded.\n" "$_SLF4J_SIMPLE_URL" >&2
		exit 1
	    fi
	    ;;

	git)
	    echo "Cloning Clouseau from $CLOUSEAU_URI ($CLOUSEAU_VSN)..."
	    check_local_clouseau_dir "$CLOUSEAU_DIR"
	    git clone --depth 1 --branch "$CLOUSEAU_VSN" "$CLOUSEAU_URI" "$CLOUSEAU_DIR"
	    ;;

	*) printf "ERROR: Invalid deployment method for Clouseau.  Please use either \`dist\` or \`git\` verbatim.\n" >&2
	   exit 1
    esac
}

if [ -z "${REBAR}" ]; then
    install_local_rebar
    REBAR=${rootdir}/bin/rebar
fi

if [ -z "${REBAR3}" ]; then
    install_local_rebar3
    REBAR3=${rootdir}/bin/rebar3
fi

if [ -z "${ERLFMT}" ]; then
    install_local_erlfmt
    ERLFMT=${rootdir}/bin/erlfmt
fi

if [ $WITH_CLOUSEAU -ne 0 ]; then
    install_local_clouseau
fi

# only update dependencies, when we are not in a release tarball
if [ -d .git  -a $SKIP_DEPS -ne 1 ]; then
    echo "==> updating dependencies"
    ${REBAR} get-deps update-deps
fi

# External repos frequently become integrated with the primary repo,
# resulting in obsolete .git directories, and possible confusion.
# It is usually a good idea to delete these .git directories.
for path in $(find src -name .git -type d); do
    git ls-files --error-unmatch $(dirname $path) > /dev/null 2>&1 && \
        echo "WARNING unexpected .git directory $path"
done

echo "You have configured Apache CouchDB, time to relax. Relax."
