#!/usr/bin/env bash
#
# Zammad backup script functions
#

function get_zammad_dir () {
  ZAMMAD_DIR="$(echo ${BACKUP_SCRIPT_PATH} | sed -e 's#/contrib/backup.*##g')"
}

function get_backup_date () {
  TIMESTAMP="$(date +'%Y%m%d%H%M%S')"

  if [ "${DEBUG}" == "yes" ]; then
    echo "timestamp is ${TIMESTAMP}"
  fi
}

function delete_old_backups () {
  test -d ${BACKUP_DIR} && find ${BACKUP_DIR}/*_zammad_*.gz -type f -mtime +${HOLD_DAYS} -delete
}

function get_db_credentials () {
  DB_ADAPTER="$(grep 'adapter:' < ${ZAMMAD_DIR}/config/database.yml | sed -e 's/.*adapter:\(\| \)//g')"
  DB_NAME="$(grep 'database:' < ${ZAMMAD_DIR}/config/database.yml | sed -e 's/.*database:\(\| \) //g')"
  DB_USER="$(grep 'username:' < ${ZAMMAD_DIR}/config/database.yml | sed -e 's/.*username:\(\| \)//g')"
  DB_PASS="$(grep 'password:' < ${ZAMMAD_DIR}/config/database.yml | sed -e 's/.*password:\(\| \)//g')"

  if [ "${DEBUG}" == "yes" ]; then
    echo "adapter=${DB_ADAPTER} dbname=${DB_NAME} dbuser=${DB_USER} dbpass=${DB_PASS}"
  fi
}

function backup_dir_create () {
  test -d ${BACKUP_DIR} || mkdir -p ${BACKUP_DIR}

  if [ "${DEBUG}" == "yes" ]; then
    echo "backup dir is ${BACKUP_DIR}"
  fi
}

function backup_files () {
  echo "creating file backup..."
  tar -C / -czf ${BACKUP_DIR}/${TIMESTAMP}_zammad_files.tar.gz --exclude='tmp' ${ZAMMAD_DIR#/}
  ln -sfn ${BACKUP_DIR}/${TIMESTAMP}_zammad_files.tar.gz ${BACKUP_DIR}/latest_zammad_files.tar.gz
}

function backup_db () {
  if [ "${DB_ADAPTER}" == "mysql2" ]; then
    echo "creating mysql backup..."
    mysqldump --opt --single-transaction -u${DB_USER} -p${DB_PASS} ${DB_NAME} | gzip > ${BACKUP_DIR}/${TIMESTAMP}_zammad_db.mysql.gz
    ln -sfn ${BACKUP_DIR}/${TIMESTAMP}_zammad_db.mysql.gz ${BACKUP_DIR}/latest_zammad_db.mysql.gz
  elif [ "${DB_ADAPTER}" == "postgresql" ]; then
    echo "creating postgresql backup..."
    su -c "pg_dump --no-privileges --no-owner -c ${DB_NAME} | \
      gzip > /tmp/${TIMESTAMP}_zammad_db.psql.gz" postgres
    mv /tmp/${TIMESTAMP}_zammad_db.psql.gz ${BACKUP_DIR}
    ln -sfn ${BACKUP_DIR}/${TIMESTAMP}_zammad_db.psql.gz ${BACKUP_DIR}/latest_zammad_db.psql.gz
  else
    echo "DB ADAPTER not found. if its sqlite backup is already saved in the filebackup"
  fi
}

function check_database_config_exists () {
  if [ -f ${ZAMMAD_DIR}/config/database.yml ]; then
    get_db_credentials
  else
    echo -e "${ZAMMAD_DIR}/config/database.yml is missing. is Zammad configured yet? \nAborting..."
    exit 1
  fi
}

function restore_warning () {
  if [ -n "${1}" ]; then
    CHOOSE_RESTORE="yes"
  else
    echo -e "The restore will delete your current config and database! \nBe sure to have a backup available! \n"
    echo -e "Enter 'yes' if you want to proceed!"
    read -p 'Restore?: ' CHOOSE_RESTORE
  fi

  if [ "${CHOOSE_RESTORE}" != "yes" ]; then
    echo "Restore aborted!"
    exit 1
  fi
}

function get_restore_dates () {
  RESTORE_FILE_DATES="$(find ${BACKUP_DIR} -type f -iname '*_zammad_files.tar.gz' | sed -e "s#${BACKUP_DIR}/##g" -e "s#_zammad_files.tar.gz##g" | sort)"

  if [ "${DB_ADAPTER}" == "postgresql" ]; then
    DB_FILE_EXT="psql"
  elif [ "${DB_ADAPTER}" == "mysql2" ]; then
    DB_FILE_EXT="mysql"
  fi

  RESTORE_DB_DATES="$(find ${BACKUP_DIR} -type f -iname "*_zammad_db.${DB_FILE_EXT}.gz" | sed -e "s#${BACKUP_DIR}/##g" -e "s#_zammad_db.${DB_FILE_EXT}.gz##g" | sort)"
}

function choose_restore_date () {
  if [ -n "${1}" ]; then
    RESTORE_FILE_DATE="${1}"
  else
    echo -e "Enter file date to restore: \n${RESTORE_FILE_DATES}"
    read -p 'File date: ' RESTORE_FILE_DATE
  fi

  if [ ! -f "${BACKUP_DIR}/${RESTORE_FILE_DATE}_zammad_files.tar.gz" ];then
    echo -e "File ${BACKUP_DIR}/${RESTORE_FILE_DATE}_zammad_files.tar.gz does not exist! \nRestore aborted!"
    exit 1
  fi

  if [ -n "${1}" ]; then
    RESTORE_DB_DATE="${1}"
  else
    echo -e "Enter db date to restore: \n${RESTORE_DB_DATES}"
    read -p 'DB date: ' RESTORE_DB_DATE
  fi

  if [ ! -f "${BACKUP_DIR}/${RESTORE_DB_DATE}_zammad_db.${DB_FILE_EXT}.gz" ];then
    echo -e "File ${BACKUP_DIR}/${RESTORE_DB_DATE}_zammad_db.${DB_FILE_EXT}.gz does not exist! \nRestore aborted!"
    exit 1
  fi
}

function detect_initcmd () {
  if [ -n "$(which systemctl 2> /dev/null)" ]; then
    INIT_CMD="systemctl"
  elif [ -n "$(which initctl 2> /dev/null)" ]; then
    INIT_CMD="initctl"
  else
    function sysvinit () {
      service $2 $1
    }
    INIT_CMD="sysvinit"
  fi

  if [ "${DOCKER}" == "yes" ]; then
    INIT_CMD="initctl"
  fi

  if [ "${DEBUG}" == "yes" ]; then
    echo "INIT CMD = ${INIT_CMD}"
  fi
}

function start_zammad () {
  echo "# Starting Zammad"
  ${INIT_CMD} start zammad
}

function stop_zammad () {
  echo "# Stopping Zammad"
  ${INIT_CMD} stop zammad
}

function restore_zammad () {
  if ! command -v zammad > /dev/null; then
    # See #3160 for the reasons of this :>
    restore_files
  fi

  if [ "${DB_ADAPTER}" == "postgresql" ]; then
    echo "# Checking requirements"

    if ! id "zammad" &> /dev/null; then
      echo "# ERROR: User 'zammad' is not present, but should be by default! #"
      echo "# Restoration was NOT successful, exiting ..."
      exit 1
    fi

    echo "# ... Dropping current database ${DB_NAME}"

    # This step is only needed for some pgsql dumps, as they don't provide a drop table statement which will cause
    # relation errors during restoration (as on package installation there's always an initialized database)
    if command -v zammad > /dev/null; then
      zammad config:set DISABLE_DATABASE_ENVIRONMENT_CHECK=1
      zammad run rake db:drop
      zammad config:set DISABLE_DATABASE_ENVIRONMENT_CHECK=0
    else
      ${ZAMMAD_DIR}/bin/rake db:drop
    fi

    echo "# ... Creating database ${DB_NAME} for owner ${DB_USER}"
    if command -v zammad > /dev/null; then
      # We'll skip this part for docker installations
      su -c "psql -c \"CREATE DATABASE ${DB_NAME} OWNER ${DB_USER};\"" postgres
    else
      ${ZAMMAD_DIR}/bin/rake db:create
    fi

    echo "# Restoring PostgrSQL DB"
    zcat ${BACKUP_DIR}/${RESTORE_DB_DATE}_zammad_db.${DB_FILE_EXT}.gz | su -c "psql -d ${DB_NAME}" zammad
  elif [ "${DB_ADAPTER}" == "mysql2" ]; then
    echo "# Restoring MySQL DB"
    zcat ${BACKUP_DIR}/${RESTORE_DB_DATE}_zammad_db.${DB_FILE_EXT}.gz | mysql -u${DB_USER} -p${DB_PASS} ${DB_NAME}
  fi

  if command -v zammad > /dev/null; then
    # See #3160 for the reasons of this :>
    restore_files
  fi

  # Ensure all data is loaded from the restored database and not the cache of the previous system state
  echo "# Clearing Cache ..."
  if command -v zammad > /dev/null; then
    zammad run rails r "Cache.clear"
  else
    ${ZAMMAD_DIR}/bin/rails r "Cache.clear"
  fi
}

function restore_files () {
  echo "# Restoring Files"
  tar -C / --overwrite -xzf ${BACKUP_DIR}/${RESTORE_FILE_DATE}_zammad_files.tar.gz
  echo "# Ensuring correct file rights ..."
  chown -R zammad:zammad ${ZAMMAD_DIR}
}

function start_backup_message () {
    echo -e "\n# Zammad backup started - $(date)!\n"
}

function start_restore_message () {
    echo -e "\n# Zammad restored started - $(date)!\n"
}

function finished_backup_message () {
    echo -e "\n# Zammad backuped successfully - $(date)!\n"
}

function finished_restore_message () {
    echo -e "\n# Zammad restored successfully - $(date)!\n"
}
