#!/bin/bash

OLD_CONF_CS40="/etc/mysql/conf.d/CS40_mysql_settings.cnf"
OLD_CONF_CS22="/etc/mysql/conf.d/CS22_mysql_settings.cnf"
NEW_CONF_CS40="/etc/mysql/override.conf.d/CS40_mysql_settings.cnf"
NEW_CONF_CS22="/etc/mysql/override.conf.d/CS22_mysql_settings.cnf"
DB_LIST="/tmp/sql_upgrade_db_list.txt"
DB_LIST_FOR_RESTORE="/tmp/sql_upgrade_db_list_restore.txt"
DB_LIST_TO_CLEAN="/tmp/sql_upgrade_db_list_clean.txt"
DUMP_FINISH="/tmp/sql_upgrade_dump_finish"
UPDATE_FINISH="/tmp/sql_upgrade_updating_finish"
CLEAN_FINISH="/tmp/sql_upgrade_cleaning_finish"
RESTORE_FINISH="/tmp/sql_upgrade_restore_finish"
CUSTOM_CNF_DIR="/etc/mysql/conf.d"
SQL_PASS_UNAME="/tmp/sqlConfing.cnf"
BROWN='\033[33m'
NC='\033[0m'
RED='\033[0;31m'
GREEN='\033[0;32m'
BACKUP_PATH="/tmp/sql_upgrade_dumps"
YELLOW='\e[1;33m'


dumpingDB() {
    SECONDS=0
    echo -e "${BROWN}\nКопируем данные из бд artix.${NC}"
    while read database; do
        echo -e "${YELLOW}Копирование бд:" $database ${NC};
        if [[ $database == "artixcs_struct" ]]; then
          # сначала бэкапируем структуру всех таблиц
          if mysqlpump --defaults-extra-file=$SQL_PASS_UNAME --add-drop-database --add-drop-table --defer-table-indexes=false --default-parallelism=100 --skip-dump-rows --databases $database | gzip > $BACKUP_PATH/$database.sql.gz; then
            # теперь бэкапируем данные для всех таблиц, кроме логов
            if mysqlpump --defaults-extra-file=$SQL_PASS_UNAME --no-create-db --no-create-info --skip-definer --defer-table-indexes=false --single-transaction --default-parallelism=100 --exclude-tables="logging_event_ext" --databases $database |
            gzip >> $BACKUP_PATH/$database.sql.gz;then
              sed -i '1d' $DB_LIST;
            else
                echo -e "${BROWN}При копировании базы artixcs_struct(данные таблиц) произошла ошибка.${NC}"
                set +e
                set +o pipefail
                exit 1
            fi
          else
              echo -e "${BROWN}При копировании базы artixcs_struct(структуры таблиц) произошла ошибка.${NC}"
              set +e
              set +o pipefail
              exit 1
          fi
        elif mysqlpump --defaults-extra-file=$SQL_PASS_UNAME --max-allowed-packet=256M --add-drop-database --add-drop-table --default-parallelism=100 --single-transaction --skip-defer-table-indexes $database | sed "s/\`index\` int(11) NOT NULL AUTO_INCREMENT/\`index\` int NOT NULL/" | gzip > $BACKUP_PATH/$database.sql.gz; then
            sed -i '1d' $DB_LIST;
        else
            echo -e "${RED}При копировании базы $database произошла ошибка.${NC}"
            set +e
            set +o pipefail
            exit 1
        fi
    done < $DB_LIST;
    touch $DUMP_FINISH;
    duration=$SECONDS
    hours=$(($duration / 3600))
    minutes=$(( ($duration % 3600)/60))
    seconds=$(( $duration % 3600 - $minutes * 60))
    echo -e "${GREEN}Закончили копирование БД, затраченное время: $hours ч. $minutes мин. $seconds сек.${NC}"
}

clearingDB(){
    SECONDS=0
    echo -e "${BROWN}Удаляем бд artix.${NC}"
    while read database; do
        echo -e "Удаляем бд $database"
        if mysql --defaults-extra-file=$SQL_PASS_UNAME -Nse "drop database $database"; then
          sed -i '1d' $DB_LIST_TO_CLEAN
        else
          echo -e "${RED}При удалении БД $database произошла ошибка.${NC}";
          set +e
          exit 1
        fi
    done < $DB_LIST_TO_CLEAN;
    echo -e "${GREEN}Очистка прошла успешно.${NC}"
    touch $CLEAN_FINISH
    duration=$SECONDS
    hours=$(($duration / 3600))
    minutes=$(( ($duration % 3600)/60))
    seconds=$(( $duration % 3600 - $minutes * 60))
    echo -e "${GREEN}Закончили удаление всех БД, затраченное время: $hours ч. $minutes мин. $seconds сек.${NC}"
}

updatingDB(){
    SECONDS=0
    echo "" > /etc/apt/preferences.d/mysql
    echo -e "${BROWN}Обновляем MySQL.${NC}"
    echo "mysql-community-server mysql-server/default-auth-override select Use Strong Password Encryption (RECOMMENDED)" | debconf-set-selections
    if ! apt-get install mysql-server -y -o Dpkg::Options::="--force-confold"; then
        echo -e "${RED}При обновлении произошла ошибка.${NC}"
        set +e
        set +o pipefail
        exit 1
    fi
    if type systemctl > /dev/null 2>&1; then
        CUSTOM_CNF_DIR="/etc/mysql/override.conf.d"
        if ! grep -q "!includedir $CUSTOM_CNF_DIR/" "/etc/mysql/mysql.cnf"; then
            echo !includedir $CUSTOM_CNF_DIR/ >> /etc/mysql/mysql.cnf
        fi
    fi
    service mysql restart --innodb-doublewrite=0  --innodb-buffer-pool-size=16G --innodb-buffer-pool-instances=32 --innodb-buffer-pool-chunk-size=1073741824 --max_allowed_packet=1G
    duration=$SECONDS
    hours=$(($duration / 3600))
    minutes=$(( ($duration % 3600)/60))
    seconds=$(( $duration % 3600 - $minutes * 60))
    echo -e "${GREEN}Закончили обновление MySQL, затраченное время: $hours ч. $minutes мин. $seconds сек.${NC}"
}

restoreDB(){
    SECONDS=0
    echo -e "${BROWN}Восстанавливаем данные бд artix.${NC}"
    echo -e "${BROWN}ВНИМАНИЕ! Восстановление большого объёма данных может занять длительное время.${NC}"
    #mysql --defaults-extra-file=$SQL_PASS_UNAME -Nse "SET GLOBAL FOREIGN_KEY_CHECKS=0; SET GLOBAL UNIQUE_CHECKS = 0; SET GLOBAL bulk_insert_buffer_size =1024*1024*256;"
    while read database; do
      echo "Восстановление бд:" $database
      mysql --defaults-extra-file=$SQL_PASS_UNAME -Nse "show variables like '%foreign%';"
      if time zcat /tmp/sql_upgrade_dumps/$database.sql.gz | mysql --defaults-extra-file=$SQL_PASS_UNAME --init-command="SET FOREIGN_KEY_CHECKS=0; SET UNIQUE_CHECKS=0; SET bulk_insert_buffer_size =1024*1024*256;"; then
          sed -i '1d' $DB_LIST_FOR_RESTORE;
          if mysql --defaults-extra-file=$SQL_PASS_UNAME -Nse "show tables" $database | grep -q "tprices"; then
              echo "Восстанавливаем оригинальную структуру таблицы tprices"
              mysql --defaults-extra-file=$SQL_PASS_UNAME -Nse "ALTER TABLE tprices MODIFY COLUMN \`index\` int auto_increment NOT NULL; ALTER TABLE tpricesTemp MODIFY COLUMN \`index\` int auto_increment NOT NULL;" $database
          fi
      else
          echo -e "${BROWN}При восстановлении произошла ошибка.${NC}"

          set +e
          set +o pipefail
          exit 1
      fi
    done < $DB_LIST_FOR_RESTORE;
    touch $RESTORE_FINISH
    duration=$SECONDS
    hours=$(($duration / 3600))
    minutes=$(( ($duration % 3600)/60))
    seconds=$(( $duration % 3600 - $minutes * 60))
    echo "seconds = $SECONDS"
    echo -e "${GREEN}Закончили восстановление данных, затраченное время: $hours ч. $minutes мин. $seconds сек.${NC}"
}


set -e
set -o pipefail

if [[ -f $NEW_CONF_CS22 || -f $NEW_CONF_CS40 ]]; then
  if [[ -f $OLD_CONF_CS22 || -f $OLD_CONF_CS40 ]]; then
    mkdir /etc/mysql/conf.d_BACKUP/
    mv $OLD_CONF_CS22 /etc/mysql/conf.d_BACKUP/CS22_mysql_settings.cnf
    mv $OLD_CONF_CS40 /etc/mysql/conf.d_BACKUP/CS40_mysql_settings.cnf
  fi
fi

if [ $(pgrep mysqld | wc -l) -ne 1 ]; then
    echo -e "${BROWN}\nMySQL недоступен. Проверьте состояние сервиса.${NC}"
    exit 1
else
    read -p "Введите имя пользователя MySQL: " sqluname
    read -sp "Введите пароль пользователя MySQL: " sqlpasswd
    printf "[client]\nuser = $sqluname\npassword = $sqlpasswd" > $SQL_PASS_UNAME; echo -e "\n"
    if ! mysql --defaults-extra-file=$SQL_PASS_UNAME -Nse ';'; then
        echo -e "${BROWN}\nВведен неверный пользователь или пароль.${NC}"
        exit 1
    fi
fi

#Создаем дампы для каждой из баз данных artix.
if [[ ! -f $DB_LIST && ! -f $DUMP_FINISH ]]; then
    mkdir -p /tmp/sql_upgrade_dumps/
    mysql --defaults-extra-file=$SQL_PASS_UNAME -Nse "show databases" | grep "artixcs\|documents" | tee $DB_LIST $DB_LIST_FOR_RESTORE $DB_LIST_TO_CLEAN >/dev/null
    if grep -xq "artixcs_struct" $DB_LIST_FOR_RESTORE; then
        sed -i '/artixcs_struct/d' $DB_LIST_FOR_RESTORE
        sed -i '1 i\artixcs_struct' $DB_LIST_FOR_RESTORE
    fi
    dumpingDB
elif [[ -f $DB_LIST && ! -f $DUMP_FINISH ]]; then
    dumpingDB
elif [[ -f $DUMP_FINISH ]]; then
    echo -e "${BROWN}\nПовторное копирование не требуется.${NC}"
fi

#Очищаем каждую из баз данных artix.
if [[ ! -f $DB_LIST_TO_CLEAN && ! -f $CLEAN_FINISH ]]; then
    clearingDB
elif [[ -f $DB_LIST_TO_CLEAN && ! -f $CLEAN_FINISH ]]; then
    clearingDB
elif [[ -f $CLEAN_FINISH ]]; then
    echo -e "${BROWN}Повторная очистка не требуется.${NC}"
fi

#Обновляем mysql.
if [[ ! -f $UPDATE_FINISH ]]; then
    updatingDB;
    if [[ "$?" -eq 0 ]]; then
        echo -e "${GREEN}Обновление прошло успешно.${NC}"
        touch $UPDATE_FINISH
    fi
else
    echo -e "${BROWN}Повторное обновление не требуется.${NC}"
fi

#Восстанавливаем дампы баз данных artix.
if [[ ! -f $RESTORE_FINISH ]]; then
    restoreDB;
elif [[ -f $RESTORE_FINISH ]]; then
    echo -e "${BROWN}\nПовторное восстановление не требуется.${NC}"
fi

rm $DB_LIST
rm $DB_LIST_FOR_RESTORE
rm $DUMP_FINISH
rm $UPDATE_FINISH
rm $CLEAN_FINISH
rm $RESTORE_FINISH
rm $SQL_PASS_UNAME
rm $DB_LIST_TO_CLEAN

set +e
set +o pipefail
