#!/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=0
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_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-version VSN      specify the version 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=1
                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=1
                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_SVN=$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
	        ;;

            --) # 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"}.
{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
}

install_local_clouseau() {
    _DIST_URL=https://github.com/cloudant-labs/clouseau/releases/download/"$CLOUSEAU_VSN"/clouseau-"$CLOUSEAU_VSN"-dist.zip
    _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"

    rm -rf "$CLOUSEAU_DIR"
    mkdir -p "$CLOUSEAU_DIR"

    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

    cat <<EOF > "$CLOUSEAU_DIR"/clouseau.ini
[clouseau]
EOF
    cat <<EOF > "$CLOUSEAU_DIR"/log4j.properties
log4j.rootLogger=debug, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %c [%p] %m%n
EOF
}

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
else
    rm -rf "$CLOUSEAU_DIR"
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."
