#!/bin/zsh
#
# This script will create a database, install some modules and run tests on it
#
# Arguments:
#
# - db host if any (will use socket if nothing is provided)
# - db user
# - other arguments are forwarded as is to the setup command.
#
# Required:
#
# - access to pg database
#
# Version 23.0.2

here=$(dirname $0)
source $here/odoo_scripts_common

# this is the same value as conf/drone/odoo.conf
if [[ -e "${project_home}/conf/drone/odoo.conf" ]];
then
    echo "$DEBUG Reading configuration from ${project_home}/conf/drone/odoo.conf"
    dbowner=$(read_configuration_key ${project_home}/conf/drone/odoo.conf options db_user)
    unaccent=$(read_configuration_key ${project_home}/conf/drone/odoo.conf options unaccent False)
# this is the same value as conf/dev/odoo.conf
elif [[ -e "${project_home}/conf/dev/odoo.conf" ]];
then
    echo "$DEBUG Reading configuration from ${project_home}/conf/dev/odoo.conf"
    dbowner=$(read_configuration_key ${project_home}/conf/dev/odoo.conf options db_user)
    unaccent=$(read_configuration_key ${project_home}/conf/dev/odoo.conf options unaccent False)
else
    dbowner=odoo
    unaccent=${unaccent-False}
    echo "$DEBUG Use default owner ($dbowner) and unaccent ($unaccent)"
fi
echo "$DEBUG Looking for modules to install"
module_list=${ODOO_SCRIPTS_MODULE_LIST-$(read_odoo_scripts_expandable_configuration_key module_list)}
modules_to_tests=${ODOO_SCRIPTS_MODULE_LIST_TESTS-$(read_odoo_scripts_expandable_configuration_key module_list_tests)}
# Install modules that will not be tested
modules_to_install=$($python -B -c "print(','.join(set('$module_list'.split(','))-set('$modules_to_tests'.split(','))))")
echo "$DEBUG module_list=$module_list"
echo "$DEBUG module_to_install=$modules_to_install"
echo "$DEBUG module_list_tests=$modules_to_tests"
if [[ -z "$modules_to_tests" ]];
then
    echo "$INFO No module to tests"
    exit 0
fi
echo "$DEBUG Looking value of fail_on_errors"
fail_on_errors=${ODOO_SCRIPTS_FAIL_ON_ERRORS-$(read_odoo_scripts_configuration_key fail_on_errors True)}
echo "$DEBUG fail_on_errors=$fail_on_errors"

# argument handling
if [[ $# -gt 0 ]];
then
    echo "$INFO Using database host $1"
    PG_HOST=-h$1
    ODOO_HOST=--db_host=$1
    shift
    if [[ $# -gt 0 ]];
    then
        echo "$INFO Using database user $1"
        PG_USER=-U$1
        ODOO_USER=--db_user=$1
        dbowner=$1
        shift
        if [[ $# -gt 0 ]];
        then
            dbname=$1
            shift
        else
            dbname=$(basename $project_home)_test
        fi
    else
        PG_USER=""
        ODOO_USER=""
    fi
else
    echo "$DEBUG No argument provided"
    PG_HOST=""
    ODOO_HOST=""
    PG_USER=""
    ODOO_USER=""
fi
if [[ -n "$INSTALL_LOG_HANDLER" ]];
then
    install_log_handler=( ${(s[,])INSTALL_LOG_HANDLER} )
    opt=( --log-handler )
    INSTALL_ARGUMENTS="$INSTALL_ARGUMENTS ${opt:^^install_log_handler}"
elif [[ -z "$INSTALL_LOG_LEVEL" ]];
then
    # default to warn if nothing set
    INSTALL_ARGUMENTS="$INSTALL_ARGUMENTS --log-level=warn"
fi
# This should be a parameter if it was simple to parse
if [[ -n "$INSTALL_LOG_LEVEL" ]];
then
    INSTALL_ARGUMENTS="$INSTALL_ARGUMENTS --log-level=${INSTALL_LOG_LEVEL}"
fi
if [[ -n "$ODOO_WITHOUT_DEMO" ]];
then
    INSTALL_ARGUMENTS="$INSTALL_ARGUMENTS --without-demo=$ODOO_WITHOUT_DEMO"
fi

if [[ -z "$ODOO_NO_DROP" ]];
then
    echo "$INFO Drop any existing database '$dbname'"
    dropdb $PG_HOST $PG_USER --if-exists $dbname --no-password
    echo "$INFO Create database '$dbname' with owner $dbowner"
    createdb $PG_HOST $PG_USER -O $dbowner $dbname --no-password || { echo "$FATAL Cannot create test database" ; exit 1; }
fi

# Add extensions
typeset -a extensions
if [[ "$unaccent" == "True" ]];
then
    extensions+=unaccent
fi
# for super project, read the configuration file
extensions+=($(read_odoo_scripts_configuration_key pg.extensions))
# for modules without configuration file, allow environment variable
# (expected format is space separated extensions
if [[ -n "$pg_extensions" ]];
then
  extensions+=( ${(s: :)pg_extensions} )
fi
echo "$DEBUG postgres extensions $extensions"
for extension in $extensions;
do
    echo "$INFO Create extension $extension in '$dbname'"
    psql $PG_HOST $PG_USER $dbname -c "CREATE EXTENSION IF NOT EXISTS $extension;"
done

echo "$INFO Modules to install: $modules_to_install"
echo "$INFO Install those modules"
logfile=$(mktemp --suffix=.log)
function clean_logfile() {
    rm $logfile
}
trap clean_logfile INT TERM
env odoo_scripts_start_logfile=$logfile $here/start $INSTALL_ARGUMENTS -i $modules_to_install -d $dbname --max-cron-threads=0 --stop-after-init $* $ODOO_HOST $ODOO_USER 2>&1 | colorize
start_status=$pipestatus[1]
if [[ $start_status -ne 0 ]];
then
    echo "$KO Cannot install modules (exit ${start_status})"
    exit $start_status
fi
criticals=$(grep ' CRITICAL' -F $logfile -c)
# exclude ALTER COLUMN xxx set not null that are not real errors
errors=$(grep ' ERROR' -F $logfile | grep -E -v "(ALTER COLUMN \"\w*\" SET NOT NULL|unable to set NOT NULL on column)" -c)
warnings=$(grep ' WARNING' -F $logfile -c)
if [[ $criticals -gt 0 ]];
then
    echo "$KO Cannot install modules ($criticals CRITICAL messages found)"
    exit 2
fi

if [[ $errors -gt 0 ]];
then
    if [[ "$fail_on_errors" == "False" ]];
    then
        echo "$WARN Install modules with $errors ERROR messages"
    else
        echo "$KO Cannot install modules ($errors ERROR messages found)"
        exit 1
    fi
else
    if [[ $warnings -gt 0 ]];
    then
        if [[ "${FAIL_ON_WARNING:-False}" == "False" ]];
        then
            echo "$WARN Modules installed ($warnings WARNING messages)"
        else
            echo "$KO Cannot install modules ($warnings WARNING messages found)"
            exit 1
        fi
    else
        echo "$OK Modules installed"
    fi
fi
echo "$INFO Run tests on $dbname"
$here/run_tests $dbname $ODOO_HOST $ODOO_USER $*
