#!/bin/bash

# Load common variables and helpers
source ./_common.sh

# Set app specific variables
app=$APPNAME
dbname=$app
dbuser=$app

# Backup the current version of the app, restore it if the upgrade fails
if sudo yunohost backup list | grep -q $app-before-upgrade > /dev/null 2>&1; then	# Supprime l'ancienne archive seulement si elle existe
	sudo yunohost backup delete $app-before-upgrade
fi
sudo yunohost backup create --ignore-hooks --apps $app --name $app-before-upgrade
EXIT_PROPERLY () {
	exit_code=$?
	if [ "$exit_code" -eq 0 ]; then
		exit 0	# Quitte sans erreur si le script se termine correctement.
	fi
	trap '' EXIT
	set +eu
	sudo yunohost app remove $app	# Supprime l'application avant de la restaurer.
	sudo yunohost backup restore --ignore-hooks $app-before-upgrade --apps $app --force	# Restore the backup if upgrade failed
	ynh_die "Upgrade failed. The app was restored to the way it was before the failed upgrade."
}
set -eu
trap EXIT_PROPERLY EXIT

# Source app helpers
source /usr/share/yunohost/helpers

# Migrate from ownCloud to Nextcloud
if [[ $YNH_APP_INSTANCE_NAME != $app ]]; then	# Si le nom de l'app donné lors de la commande n'est pas nextcloud, vérifie si c'est owncloud pour lancer la migration.
  [[ $YNH_APP_ID == owncloud ]] \
    || ynh_die "Incompatible application to migrate to Nextcloud"

  # check that Nextcloud is not already installed
  (sudo yunohost app list --installed -f "$app" | grep -q id) \
    && ynh_die "Nextcloud is already installed"

  # retrieve ownCloud app settings
  real_app=$YNH_APP_INSTANCE_NAME	# real_app prend le nom de owncloud.
  domain=$(ynh_app_setting_get "$real_app" domain)
  oc_dbpass=$(ynh_app_setting_get "$real_app" mysqlpwd)
  oc_dbname=$real_app
  oc_dbuser=$real_app

  # remove nginx and php-fpm configuration files
  sudo rm -f \
      "/etc/nginx/conf.d/${domain}.d/${real_app}.conf" \
      "/etc/php5/fpm/pool.d/${real_app}.conf" \
      "/etc/cron.d/${real_app}"

  # reload services to disable php-fpm and nginx config for ownCloud
  sudo service php5-fpm reload || true
  sudo service nginx reload || true

  # remove dependencies package
  ynh_package_remove owncloud-deps || true

  # clean new destination and data directories
  DESTDIR="/var/www/$app"
  DATADIR="/home/yunohost.app/${app}/data"
  SECURE_REMOVE '$DESTDIR'	# Supprime le dossier de nextcloud dans /var/www le cas échéant
  SECURE_REMOVE '/home/yunohost.app/$app'	# Et dans yunohost.app

  # rename ownCloud folders
  sudo mv "/var/www/$real_app" "$DESTDIR"	# Puis renomme les dossiers de owncloud en nextcloud
  sudo mv "/home/yunohost.app/$real_app" "/home/yunohost.app/$app"
  sudo sed -ri "s#^(\s*'datadirectory' =>).*,#\1 '${DATADIR}',#" \
      "/var/www/${app}/config/config.php"	# Change l'emplacement du dossier de data dans le fichier de config

  # rename the MySQL database
  rename_mysql_db "$oc_dbname" "$oc_dbuser" "$oc_dbpass" "$dbname" "$dbuser"
  sudo sed -ri "s#^(\s*'dbname' =>).*,#\1 '${dbname}',#" \
      "/var/www/${app}/config/config.php"
  sudo sed -ri "s#^(\s*'dbuser' =>).*,#\1 '${dbuser}',#" \
      "/var/www/${app}/config/config.php"

  # rename ownCloud system group and account
  sudo groupmod -n "$app" "$real_app"
  sudo usermod -l "$app" "$real_app"
else
  real_app=$app

  # handle old migrations from ownCloud
  curr_dbname=$(sudo cat "/var/www/${app}/config/config.php" \
      | grep dbname | sed "s|.*=> '\(.*\)'.*|\1|g")	 # Prend le nom de la bdd dans le fichier de config
  if [[ $curr_dbname != $dbname ]]; then	# Si le nom de la base de donnée n'est pas nextcloud, renomme la base de donnée.
    curr_dbuser=$(sudo cat "/var/www/${app}/config/config.php" \
        | grep dbuser | sed "s|.*=> '\(.*\)'.*|\1|g")	 # Prend le nom d'utilisateur de la bdd
    dbpass=$(ynh_app_setting_get "$real_app" mysqlpwd)

    # rename the MySQL database
    rename_mysql_db "$curr_dbname" "$curr_dbuser" "$dbpass" "$dbname" "$dbuser"
    sudo sed -ri "s#^(\s*'dbname' =>).*,#\1 '${dbname}',#" \
        "/var/www/${app}/config/config.php"
    sudo sed -ri "s#^(\s*'dbuser' =>).*,#\1 '${dbuser}',#" \
        "/var/www/${app}/config/config.php"
  fi
fi

# Retrieve app settings
domain=$(ynh_app_setting_get "$real_app" domain)
path=$(ynh_app_setting_get "$real_app" path)
path=${path%/}
dbpass=$(ynh_app_setting_get "$real_app" mysqlpwd)
user_home=$(ynh_app_setting_get "$real_app" user_home)

# Check destination directory
DESTDIR="/var/www/$app"
[[ ! -d $DESTDIR ]] && ynh_die \
"The destination directory '$DESTDIR' does not exist.\
 The app is not correctly installed, you should remove it first."

# Check app's data directory
DATADIR="/home/yunohost.app/${app}/data"
[[ ! -d $DATADIR ]] && ynh_die \
"The data directory '$DATADIR' does not exist.\
 The app is not correctly installed, you should remove it first."

# Upgrade dependencies
ynh_package_install_from_equivs ../conf/${DEPS_PKG_NAME}.control \
  || ynh_die "Unable to upgrade dependencies"

# FIXME: Delete current nginx configuration to be able to check if
# .well-known is already served. See https://dev.yunohost.org/issues/400
nginx_conf="/etc/nginx/conf.d/${domain}.d/${app}.conf"
sudo rm -f "$nginx_conf"
sudo service nginx reload

# Copy and set nginx configuration
sed -i "s@#APP#@${app}@g"          ../conf/nginx.conf
sed -i "s@#PATH#@${path}@g"        ../conf/nginx.conf
sed -i "s@#LOCATION#@${path:-/}@g" ../conf/nginx.conf
sed -i "s@#DESTDIR#@${DESTDIR}@g"  ../conf/nginx.conf
# do not serve .well-known if it's already served on the domain
if is_url_handled "https://${domain}/.well-known/caldav" ; then
  sed -ri '/^location = \/\.well\-known\/(caldav|carddav) \{/,/\}/d' \
      ../conf/nginx.conf
fi
sudo cp ../conf/nginx.conf "$nginx_conf"

# Copy and set php-fpm configuration
phpfpm_conf="/etc/php5/fpm/pool.d/${app}.conf"
sed -i "s@#USER#@${app}@g"         ../conf/php-fpm.conf
sed -i "s@#GROUP#@${app}@g"        ../conf/php-fpm.conf
sed -i "s@#POOLNAME#@${app}@g"     ../conf/php-fpm.conf
sed -i "s@#DESTDIR#@${DESTDIR}/@g" ../conf/php-fpm.conf
sudo cp ../conf/php-fpm.conf "$phpfpm_conf"
sudo chown root: $phpfpm_conf
sudo chmod 644 $phpfpm_conf

# Set system group in hooks
sed -i "s@#GROUP#@${app}@g" ../hooks/post_user_create

# occ helper for the current installation
_exec_occ() {
  exec_occ "$DESTDIR" "$app" $@	# Appel de php occ avec les droits de l'user nextcloud. A noter que ce n'est là que la déclaration de la fonction qui sera appelée plus tard.
}

# Retrieve new Nextcloud sources in a temporary directory
TMPDIR=$(mktemp -d)
extract_nextcloud "$TMPDIR"	# Télécharge nextcloud, vérifie sa somme de contrôle et le décompresse.

# Copy Nextcloud configuration file
nc_conf="${DESTDIR}/config.json"
sed -i "s@#DOMAIN#@${domain}@g" ../conf/config.json
sed -i "s@#DATADIR#@${DATADIR}@g" ../conf/config.json
sudo cp ../conf/config.json "${TMPDIR}/config.json"

# Enable maintenance mode
_exec_occ maintenance:mode --on

# Copy config and 3rd party applications from current directory
sudo cp -a "${DESTDIR}/config/config.php" "${TMPDIR}/config/config.php"
for a in $(sudo ls "${DESTDIR}/apps"); do
  [[ ! -d "${TMPDIR}/apps/$a" ]] \
    && sudo cp -a "${DESTDIR}/apps/$a" "${TMPDIR}/apps/$a"
done

# Rename existing app directory and move new one
SECURE_REMOVE '${DESTDIR}'	# Supprime le dossier actuel de nextcloud
sudo mv "$TMPDIR" "$DESTDIR"	# Et le remplace par la nouvelle version du dossier temporaire

# Set app folders ownership
sudo chown -R $app: "$DESTDIR" "$DATADIR"

# Upgrade Nextcloud (SUCCESS = 0, UP_TO_DATE = 3)
# TODO: Restore old directory in case of failure?
_exec_occ maintenance:mode --off
_exec_occ upgrade \
  || ([[ $? -eq 3 ]] || ynh_die "Unable to upgrade Nextcloud")

# Ensure that UpdateNotification app is disabled
_exec_occ app:disable updatenotification

# Enable plugins and set Nextcloud configuration
_exec_occ app:enable user_ldap
_exec_occ config:import "$nc_conf"
sudo rm -f "$nc_conf"

# Guess user_home value if empty
if [[ -z "${user_home:-}" ]]; then	# user_home correspond au champs "Access the users home folder from Nextcloud?" du manifest
  sudo cat "${DATADIR}/mount.json" >/dev/null 2>&1 \
    && user_home=1 \
    || user_home=0	# Test l'existence du fichier mount.json pour connaître la valeur de user_home, dans le cas où la valeur ne serait pas renseignée. (Mais ce fichier semble ne plus exister...)
  ynh_app_setting_set "$real_app" user_home "$user_home"
fi

# Enable External Storage and create local mount to home folder as needed
if [[ ${user_home} -eq 1 ]]; then
  _exec_occ app:enable files_external
  _exec_occ files_external:list --output=json \
      | grep -q '"storage":"\\\\OC\\\\Files\\\\Storage\\\\Local"' \
    || create_home_external_storage '_exec_occ'
fi

# Add dynamic logout URL to the config
# TODO: if changes are made to this section, replace it with new one.
_exec_occ config:system:get logout_url >/dev/null 2>&1 \
  || sudo su -c "echo \"
//-YunoHost-
// set logout_url according to main domain
\\\$main_domain = exec('cat /etc/yunohost/current_host');
\\\$CONFIG['logout_url'] = 'https://'.\\\$main_domain.'/yunohost/sso/?action=logout';
//-YunoHost-
\" >> ${DESTDIR}/config/config.php" -- $app

# Iterate over users to extend their home folder permissions - for the external
# storage plugin usage - and create relevant Nextcloud directories
for u in $(ynh_user_list); do
  sudo mkdir -p "${DATADIR}/${u}"
  sudo setfacl -m g:$app:rwx "/home/$u" || true
done

# Fix app ownerships & permissions
sudo find ${DESTDIR}/ -type f -print0 | sudo xargs -0 chmod 0644
sudo find ${DESTDIR}/ -type d -print0 | sudo xargs -0 chmod 0755
sudo find ${DATADIR}/ -type f -print0 | sudo xargs -0 chmod 0640
sudo find ${DATADIR}/ -type d -print0 | sudo xargs -0 chmod 0750
sudo chmod 640 "${DESTDIR}/config/config.php"
sudo chmod 755 /home/yunohost.app

# Set SSOwat rules
ynh_app_setting_set "$real_app" unprotected_uris "/"
ynh_app_setting_set "$real_app" skipped_regex \
    "$(sed 's/[\.\-]/\%&/g' <<< $domain)/%.well%-known/.*"

# Reload services
sudo service php5-fpm restart || true
sudo service nginx reload || true

# Add cron job
cron_path="/etc/cron.d/$app"
sed -i "s@#USER#@${app}@g"        ../conf/nextcloud.cron
sed -i "s@#DESTDIR#@${DESTDIR}@g" ../conf/nextcloud.cron
sudo cp ../conf/nextcloud.cron "$cron_path"
sudo chmod 644 "$cron_path"
_exec_occ background:cron

# Finish ownCloud migration
if [[ $real_app != $app ]]; then
  echo "ownCloud has been successfully migrated to Nextcloud! \
A last scheduled operation will run in a couple of minutes to finish the \
migration in YunoHost side. Do not proceed any application operation while \
you don't see Nextcloud as installed." >&2

  # install cron job and script for final migration step
  script_path="/usr/local/sbin/owncloud-migration.sh"
  sed -i "s@#APP#@${real_app}@g" ../conf/owncloud-migration.sh
  sudo cp ../conf/owncloud-migration.sh "$script_path"
  sudo chmod 755 "$script_path"
  cron_path="/etc/cron.d/owncloud-migration"
  echo "*/1 * * * * root $script_path" | sudo tee "$cron_path" >/dev/null
  sudo chmod 644 "$cron_path"
fi

# Warn about possible disabled apps
echo "Note that if you've installed some third-parties Nextcloud applications, \
they are probably disabled and you'll have to manually activate them again." >&2