#!/bin/sh -e
# __nextcloud/gencode-remote

# Install if not installed

# Legacy:
# curl -sS -L '$nextcloud_uri' | tar xj --strip-components=1 nextcloud/


# Call the nextcloud occ script as the designed user. Maybe this can be a bit
# more effictive with user switching, but currently the easiest way of doing
# it.
#
# All arguments are directly passed to occ (injection alarm ;-) )
occ() {
    # su creates a new shell, so it does not affect the current session
    #  will not use -q as it supresses errors, too
    cat << SHELL
su -s /bin/sh -l "$user" -- -e <<'SU'
cd '$installdir' && php occ --no-warnings --no-interaction --no-ansi $@
SU
SHELL
}

# Turn the maintainer mode on, but print it only once at all.
#
# No arguments.
occ_maintainer_mode_on() {
    # Check if this was not already done
    if [ "$_maintainer_mode_on" != "yes" ]; then
        occ maintenance:mode --on
        _maintainer_mode_on="yes"
    fi
}

# Print the value of the given configuration.
#
# Arguments:
#  1: the nextcloud configuration name
getparam() {
    awk -v FS=" = " -v name="$1" '
             function ntostring(n) { ret=""; for(i=n; i<=NF; i++) ret=ret $i (i<NF ? OFS : ""); return ret }
             $1 == name { print ntostring(2); }
             ' "$__object/explorer/config"
}

# Get existing versions
version_is="$( cat "$__object/explorer/version" )"
version_should="$( cat "$__object/parameter/version" )"

# the install directory
installdir="/$__object_id"
tarballdir="$(dirname "$installdir")/.$(basename "$installdir")"

# get used user and group
user="$( cat "$__object/parameter/user" )"
group="$( cat "$__object/parameter/group" )"



# Detect if we can install or upgrade.
# Check if this will be a new installation.
if [ -z "$version_is" ]; then
    install="yes"

# Check if upgrades are available. Not do this if it's not wanted by the user.
elif ! [ -f "$__object/parameter/install-only" ]; then
    # installation upgrade
    if [ "$version_is" != "$version_should" ]; then
        upgrade="yes"
    fi
fi


# Check if the installation will be upgraded.
# Remove the old folder and replace it with the new one.
if [ "$upgrade" ]; then
    cat << REMOTE
chown '$user':'$group' -R '$tarballdir'
REMOTE

    # no more changes from the user
    occ_maintainer_mode_on
    cat << REMOTE

cp -pf '$installdir/config/config.php' '$tarballdir/config/config.php'
mv '$installdir/data' '$tarballdir'

rm -rf '$installdir'
mv '$tarballdir' '$installdir'

REMOTE

    # do some maintainer stuff
    occ upgrade
    # gamble a bit with database maintainer commands
    occ db:add-missing-primary-keys
    occ db:add-missing-columns
    occ db:add-missing-indices
    occ db:convert-filecache-bigint

    # send upgrade message
    printf "upgraded %s to %s\n" "$version_is" "$version_should" >> "$__messages_out"

# Apply some misc to the installation folder.
elif [ "$install" ]; then
    # Maintainer mode is not available before installation

    # Correct all file permissions of the new installation
    cat << REMOTE
chown '$user':'$group' -R '$installdir'
REMOTE
fi


# Check if the nextcloud application needs to be installed.
# This checks the state of the configuration, not of the directory.
#
# shellcheck disable=SC2089  # disabled to write args string
if ! grep -q -F "installed = 1" "$__object/explorer/config"; then
    # argument construction
    occ_install_args=""

    # Error function if value not found
    die_err() {
        echo "parameter not found but required; can't continue!!" >&2
        exit 1
    }
    # Database setup for mysql and pgsql
    db_setup() {
        # add type and other database values
        occ_install_args="$occ_install_args --database '$1'"
        occ_install_args="$occ_install_args --database-host '$(cat "$__object/parameter/database-host" || die_err)'"
        occ_install_args="$occ_install_args --database-name '$(cat "$__object/parameter/database-name" || die_err)'"
        occ_install_args="$occ_install_args --database-user '$(cat "$__object/parameter/database-user" || die_err)'"
        occ_install_args="$occ_install_args --database-pass '$(cat "$__object/parameter/database-password" || die_err)'"

        db_prefix="$__object/parameter/database-prefix"
        if [ -f "$db_prefix" ]; then
            occ_install_args="$occ_install_args --database-table-prefix '$(cat "$db_prefix")'"
        fi
    }

    database_type="$(cat "$__object/parameter/database-type")"
    case "$database_type" in
        sqlite3)
            occ_install_args="$occ_install_args --database sqlite"
            ;;
        mysql)
            db_setup mysql
            ;;
        pgsql)
            db_setup pgsql
            ;;

        *)
            printf "Database type '%s' is unkown!\n" "$database_type" >&2
            exit 3
            ;;
    esac

    # Admin stuff
    occ_install_args="$occ_install_args --admin-pass '$(cat "$__object/parameter/admin-password")'"

    admin_user="$__object/parameter/admin-user"
    if [ -f "$admin_user" ]; then
        occ_install_args="$occ_install_args --admin-user '$(cat "$admin_user")'"
    fi
    admin_email="$__object/parameter/admin-email"
    if [ -f "$admin_email" ]; then
        occ_install_args="$occ_install_args --admin-email '$(cat "$admin_email")'"
    fi

    # Data directory
    datadir="$__object/parameter/data-directory"
    if [ -f "$datadir" ]; then
        occ_install_args="$occ_install_args --data-dir '$(cat "$datadir")'"
    fi


    # Execute the install command.
    # generated parameters will be splited in the remote shell
    occ maintenance:install "$occ_install_args"

    # send install message
    echo installed >> "$__messages_out"
fi


# Handle the config
mkdir "$__object/files"
"$__type/map-conf-changes.sh" > "$__object/files/conf-cmds"

# only print if there are changes listed
if [ -s "$__object/files/conf-cmds" ]; then
    # save that we did changes
    changes="yes"
    occ_maintainer_mode_on

    # print change commands incl. the switch of user context
    #  using -e to abort if the commands failed
    printf "su -s /bin/sh -l '%s' -- -e << 'SU'\n" "$user"
    printf "cd '%s'\n" "$installdir"
    cat "$__object/files/conf-cmds"
    printf "SU\n"
fi


# Get the current and future data directory
data_old="$(getparam datadirectory)"
data_new="$(cat "$__object/parameter/data-directory" 2>/dev/null || printf "%s/data" "$installdir")"

# Move if they should be moved. Avoid false positives if $data_old is empty
if [ "$data_old" ] && [ "$data_old" != "$data_new" ]; then
    # save that we did changes
    changes="yes"
    occ_maintainer_mode_on

    # Change the configuration variable and then move the folder. This order is
    # important if SQLite is used, but the config already corrupted if it can
    # not be moved.
    occ config:system:set datadirectory --type=string --value "'$data_new'"
    cat << REMOTE
cd '$installdir'  # only for the users safety

rm -rf '$data_new'
mkdir -p '$(dirname "$data_new")'  # if the parent not exists
mv -T '$data_old' '$data_new'

REMOTE
fi

# Print configured message if changes where done to the configuration
if [ "$changes" ]; then
    echo configured >> "$__messages_out"
fi


# Check if this is the fist install
if [ "$install" ]; then
    # do some convert stuff etc.

    # variable accessible from the last $install if-clause
    case "$database_type" in
        mysql)
            # only available for mysql
            occ db:convert-mysql-charset
            ;;
    esac

    occ db:convert-filecache-bigint
fi

# Disable maintainer mode
if [ "$_maintainer_mode_on" = "yes" ]; then
    occ maintenance:mode --off
fi
