#!/bin/bash

YELLOW='\033[0;33m'
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'

spinner() {
    local pid=$1
    local delay=0.1
    local spinstr='|/-\'
    while kill -0 $pid 2>/dev/null; do
        local temp=${spinstr#?}
        printf " ${YELLOW}[%c]${NC}  " "$spinstr"
        spinstr=$temp${spinstr%"$temp"}
        sleep $delay
        printf "\b\b\b\b\b\b"
    done
    printf "     \b\b\b\b\b"
}

restore_clickhouse_db() {
    echo "Restoring clickhouse db from dump 'ch_backup.zip'..."
    BACKUP_ROOT_DIR="backups"
    if [ ! "/$BACKUP_ROOT_DIR" ]; then
        echo -e "${RED}Error:${NC} Backup file $BACKUP_ROOT_DIR does not exist."
        exit 1
    fi

    clickhouse-client --host=$host --port=$ch_port --user=$user --password=$password --query="SELECT name FROM system.disks WHERE name='backups';"
    if [ $? -ne 0 ]; then
        echo "Disk 'backups' is not available. Check configuration."
        exit 1
    fi

    local query="RESTORE DATABASE $ch_db_name_from AS $ch_db_name_to FROM Disk ('$BACKUP_ROOT_DIR', 'ch_backup.zip')"
    clickhouse-client --host=$host --port=$ch_port --user=$user --password=$password --query="$query"

    if [ $? -eq 0 ]; then
        echo -e "${GREEN}Restore clickhouse completed successfully.${NC}"
    else
        echo -e "${RED}Restore failed.${NC}"
        exit 1
    fi
}

run_with_spinner() {
    local full_command="$*"

    echo "Executing: ${full_command}..."

    "$@" &
    local cmd_pid=$!

    spinner "$cmd_pid"
    wait "$cmd_pid"

    if [ $? -eq 0 ]; then
        echo -e "${GREEN}Command successed: ${full_command}${NC}"
    else
        echo -e "${RED}Command error: ${full_command}${NC}"
        exit 1
    fi
}

restore_dump() {
    local dump_file="$1"

    local base_name=$(basename "$dump_file")
    local table_name="${base_name%.sql}"

    echo "Restoring table '$table_name' from dump '$dump_file'..."

    PGPASSWORD="$password" pg_restore -d "$db_name" -U "$user" -h "$host" -p "$psql_port" "$dump_file" &
    local restore_pid=$!

    spinner "$restore_pid"
    wait "$restore_pid"

    if [ $? -eq 0 ]; then
        echo -e "${GREEN}Table '$table_name' was restored successfully from '$dump_file'${NC}"
    else
        echo -e "${RED}Error restoring table '$table_name' from '$dump_file'${NC}"
        exit 1
    fi
}

restore_sql_file() {
    local sql_file="$1"

    local base_name=$(basename "$sql_file")
    local table_name="${base_name%.sql}"

    echo "Restoring table '$table_name' from sql file '$sql_file'..."

    PGPASSWORD="$password" psql -U "$user" -d "$db_name" -h "$host" -p "$psql_port" -1 -f "$sql_file" --single-transaction &
    local psql_pid=$!

    spinner "$psql_pid"
    wait "$psql_pid"

    if [ $? -eq 0 ]; then
        echo -e "${GREEN}Table '$table_name'  was restored successfully from '$sql_file'${NC}"
    else
        echo -e "${RED}Error restoring table '$table_name' from '$sql_file'${NC}"
        exit 1
    fi
}

host=$1
user=$2
password=$3
db_name=$4
psql_port=$5
ch_def_user_password=$6
ch_db_name_from=$7
ch_db_name_to=$8
ch_port=$9
license=${10}

if [ "$host" == "0.0.0.0" ] || [ "$host" == "localhost" ]
then
    python3 src/py_utils/service.py evi-scud stop
    if [ $? -ne 0 ]
    then
        exit 1
    fi

    python3 src/py_utils/service.py evi-core stop
    if [ $? -ne 0 ]
    then
        exit 1
    fi

    python3 src/py_utils/service.py evi-live stop
    if [ $? -ne 0 ]
    then
        exit 1
    fi

    python3 src/py_utils/service.py evi-analyzer stop
    if [ $? -ne 0 ]
    then
        exit 1
    fi

    python3 src/py_utils/docker.py evi-analytics stop
    if [ $? -ne 0 ]
    then
        exit 1
    fi

    python3 src/py_utils/service.py evi-archive stop
    if [ $? -ne 0 ]
    then
        exit 1
    fi

    python3 src/py_utils/service.py postgresql restart
    if [ $? -ne 0 ]
    then
        exit 1
    fi

    python3 src/py_utils/service.py clickhouse-server restart
    if [ $? -ne 0 ]
    then
        exit 1
    fi

    su postgres -c "psql -c \"create user $user;\""
    su postgres -c "psql -c \"ALTER USER $user WITH PASSWORD '$password';\""
    su postgres -c "psql -c \"ALTER USER $user WITH SUPERUSER;\""

    su postgres -c "psql -c \"DROP DATABASE IF EXISTS $db_name;\""
    su postgres -c "psql -c \"CREATE DATABASE $db_name;\""

    echo "PostgreSQL configured"

    clickhouse-client --host=$host --port=$ch_port --user=default --password=$ch_def_user_password --query="CREATE USER IF NOT EXISTS $user IDENTIFIED WITH sha256_password BY '$password'" --query="GRANT CURRENT GRANTS on *.* TO $user WITH GRANT OPTION"
    clickhouse-client --host=$host --port=$ch_port --user=default --password=$ch_def_user_password --query="DROP DATABASE IF EXISTS $ch_db_name_to"
    clickhouse-client --host=$host --port=$ch_port --user=$user --password=$password --query="CREATE DATABASE IF NOT EXISTS $ch_db_name_to"

    echo "Clickhouse configured"
fi

PGPASSWORD=$password psql -X -h $host -U $user -d $db_name -p $psql_port -c "CREATE SCHEMA IF NOT EXISTS evi;"

rm -rf restores
mkdir restores -p

if [ $license == "true" ] || [ $license == 0 ]; then
    restore_dump "./dumps/license_params.sql"
fi

run_with_spinner python3 src/py_utils/preconf.py ./restores/preconf.sql
restore_sql_file "./restores/preconf.sql"

run_with_spinner python3 src/py_utils/gen_user_dump.py ./dumps/users.csv ./restores/user.sql
restore_sql_file "./restores/user.sql"

restore_dump "./dumps/apikey.sql"


run_with_spinner python3 src/py_utils/gen_organization_dump.py ./dumps/organization.csv ./restores/organization.sql
restore_sql_file "./restores/organization.sql"

run_with_spinner python3 src/py_utils/gen_division_dump.py ./dumps/division.csv ./restores/division.sql
restore_sql_file "./restores/division.sql"

run_with_spinner python3 src/py_utils/gen_position_dump.py ./dumps/position.csv ./restores/position.sql
restore_sql_file "./restores/position.sql"

restore_dump "./dumps/location.sql"

run_with_spinner python3 src/py_utils/gen_camera_dump.py ./dumps/camera.csv ./restores/camera.sql
restore_sql_file "./restores/camera.sql"

restore_dump "./dumps/camera_detection_schedule.sql"
restore_dump "./dumps/streams.sql"
restore_dump "./dumps/analytics_schedule.sql"

restore_dump "./dumps/camera_stream.sql"
restore_dump "./dumps/camera_archive_schedule.sql"
restore_dump "./dumps/views.sql"

run_with_spinner python3 src/py_utils/gen_access_views_dump.py ./dumps/access_views.csv ./restores/access_views.sql
restore_sql_file "./restores/access_views.sql"

restore_dump "./dumps/cell_views.sql"

run_with_spinner python3 src/py_utils/gen_photo_dump.py ./dumps/photo.csv ./restores/photo
for file in ./restores/photo_*.sql; do
    restore_sql_file "$file"
done

run_with_spinner python3 src/py_utils/gen_car_dump.py ./dumps/car.csv ./restores/car.sql
restore_sql_file "./restores/car.sql"

restore_dump "./dumps/access_level_worker.sql"

run_with_spinner python3 src/py_utils/gen_worker_dump.py ./dumps/worker.csv ./restores/worker.sql
restore_sql_file "./restores/worker.sql"

run_with_spinner python3 src/py_utils/gen_worker_car_dump.py ./dumps/worker_car.csv ./restores/worker_car.sql
restore_sql_file "./restores/worker_car.sql"

restore_dump "./dumps/worker_urv.sql"
restore_dump "./dumps/pass_info.sql"
restore_dump "./dumps/calendar.sql"
restore_dump "./dumps/calendar_day_time.sql"
restore_dump "./dumps/calendar_dates.sql"
restore_dump "./dumps/schedule.sql"
restore_dump "./dumps/access_level_controller.sql"

run_with_spinner python3 src/py_utils/gen_controller_dump.py ./dumps/controller.csv ./restores/controller.sql
restore_sql_file "./restores/controller.sql"

restore_dump "./dumps/not_acked_event_cache.sql"
restore_dump "./dumps/controller_cached.sql"
restore_dump "./dumps/relay.sql"
restore_dump "./dumps/reader.sql"

restore_dump "./dumps/discrete_input.sql"

restore_dump "./dumps/access_pattern.sql"
restore_dump "./dumps/access_pattern_relay.sql"
restore_dump "./dumps/card.sql"
restore_dump "./dumps/worker_card.sql"
restore_dump "./dumps/worker_calendar.sql"
restore_dump "./dumps/worker_access_pattern.sql"
restore_dump "./dumps/guest_access_pattern.sql"

run_with_spinner python3 src/py_utils/gen_pass_event_dump.py ./dumps/pass_event.csv ./restores/pass_event
for file in ./restores/pass_event_*.sql; do
    restore_sql_file "$file"
done

restore_dump "./dumps/guest_pass_event.sql"
restore_dump "./dumps/settings.sql"
restore_dump "./dumps/firmware.sql"
restore_dump "./dumps/update_plan.sql"

run_with_spinner python3 src/py_utils/gen_guest_dump.py ./dumps/guest.csv ./restores/guest.sql
restore_sql_file "./restores/guest.sql"

run_with_spinner python3 src/py_utils/gen_visit_purpose_dump.py ./dumps/visit_purposes.csv ./restores/visit_purpose.sql
restore_sql_file "./restores/visit_purpose.sql"

restore_dump "./dumps/visit.sql"

run_with_spinner python3 src/py_utils/gen_visit_dump.py ./dumps/visit2.csv ./restores/visit2.sql
restore_sql_file "./restores/visit2.sql" # мигрировать только после создания таблиц evi.calendar, evi.calendar_day_time, evi.calendar_dates

restore_dump "./dumps/visit_card.sql"
restore_dump "./dumps/visit_card_history.sql"
restore_dump "./dumps/interactive_plan.sql"
restore_dump "./dumps/entity_plan_position.sql"
restore_dump "./dumps/critical_event.sql"

run_with_spinner python3 src/py_utils/gen_triggers_dump.py ./dumps/triggers.csv ./restores/triggers.sql
restore_sql_file "./restores/triggers.sql"

run_with_spinner python3 src/py_utils/gen_faces_dump.py ./dumps/faces.csv ./restores/faces.sql
restore_sql_file "./restores/faces.sql"

restore_dump "./dumps/lines.sql"
restore_dump "./dumps/masks.sql"
restore_dump "./dumps/maskspoints.sql"
restore_dump "./dumps/stream_params.sql"

restore_dump "./dumps/zonepoints.sql"
restore_dump "./dumps/zones.sql"

restore_clickhouse_db

exit 0
