#!/bin/bash
# setup_postgres_clusters.sh
# Полный скрипт развертывания PostgreSQL 16 с тремя кластерами

set -e  # Остановка при ошибке

# ===========================================
# КОНФИГУРАЦИЯ
# ===========================================

PG_VERSION="16"

# Конфигурация кластеров
declare -A CLUSTER_CONFIGS
CLUSTER_CONFIGS["freesurf"]="5432|freesurf|freesurf|freesurf|gXGQZ_w44f05_IbKF3bBkAJK99_r2R2C"
CLUSTER_CONFIGS["ghostway"]="5433|ghostway|ghostway|ghostway|BHySDRAiYX-bUamciAQsbt3Y70M6PJlI"
CLUSTER_CONFIGS["testbot"]="5434|testbot|testbot|testbot|ONRx-deA5PHYAfk-Pl7sUt-8lldiX2hn"

# Разрешенные внешние IP для доступа
ALLOWED_IPS=(
    "212.124.22.219"
    "185.71.81.102"
    "188.191.17.167"
    "92.51.13.47"
)

# Цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# ===========================================
# ФУНКЦИИ
# ===========================================

log() {
    echo -e "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}

print_header() {
    echo ""
    echo "========================================="
    echo -e "${BLUE}$1${NC}"
    echo "========================================="
}

check_error() {
    if [ $? -ne 0 ]; then
        log "${RED}✗ ОШИБКА: $1${NC}"
        exit 1
    fi
}

# ===========================================
# 1. ОСТАНОВКА И ОЧИСТКА СУЩЕСТВУЮЩИХ КЛАСТЕРОВ
# ===========================================

print_header "1. Остановка и очистка существующих кластеров"

log "Остановка всех служб PostgreSQL..."
systemctl stop postgresql 2>/dev/null || true
systemctl stop postgresql@*.service 2>/dev/null || true
pkill -u postgres 2>/dev/null || true
sleep 2

log "Удаление существующих кластеров..."
for CLUSTER in freesurf ghostway testbot main; do
    log "  Удаление кластера $CLUSTER..."
    pg_ctlcluster $PG_VERSION $CLUSTER stop 2>/dev/null || true
    pg_dropcluster $PG_VERSION $CLUSTER --stop 2>/dev/null || true
done

log "Очистка PID файлов..."
rm -f /var/run/postgresql/*.pid 2>/dev/null || true
rm -f /run/postgresql/*.pid 2>/dev/null || true

log "Проверка свободных портов..."
for port in 5432 5433 5434; do
    if lsof -i :$port > /dev/null 2>&1; then
        log "${YELLOW}⚠ Порт $port занят, освобождаем...${NC}"
        fuser -k $port/tcp 2>/dev/null || true
        sleep 1
    fi
    log "  Порт $port: ${GREEN}свободен${NC}"
done

# ===========================================
# 2. УСТАНОВКА POSTGRESQL 16
# ===========================================

print_header "2. Установка PostgreSQL $PG_VERSION"

# Проверяем, установлен ли PostgreSQL
if command -v psql &> /dev/null; then
    CURRENT_VERSION=$(psql --version 2>/dev/null | grep -oP '(?<=PostgreSQL )\d+' || echo "0")
    log "${GREEN}✓ PostgreSQL уже установлен (версия $CURRENT_VERSION)${NC}"
    
    if [ "$CURRENT_VERSION" != "$PG_VERSION" ]; then
        log "${YELLOW}⚠ Текущая версия $CURRENT_VERSION, устанавливаем $PG_VERSION параллельно${NC}"
    fi
fi

# Устанавливаем PostgreSQL 16
log "Установка PostgreSQL $PG_VERSION..."

# Добавляем репозиторий PostgreSQL
log "  Добавление официального репозитория PostgreSQL..."
apt-get update -qq
apt-get install -y -qq wget ca-certificates lsb-release gnupg 2>/dev/null || true

# Добавляем ключ репозитория
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - 2>/dev/null || true

# Добавляем репозиторий
echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list

# Обновляем список пакетов
log "  Обновление списка пакетов..."
apt-get update -qq

# Устанавливаем PostgreSQL
log "  Установка пакетов postgresql-$PG_VERSION и postgresql-client-$PG_VERSION..."
apt-get install -y -qq postgresql-$PG_VERSION postgresql-client-$PG_VERSION

log "${GREEN}✓ PostgreSQL $PG_VERSION успешно установлен${NC}"

# ===========================================
# 3. СОЗДАНИЕ НОВЫХ КЛАСТЕРОВ
# ===========================================

print_header "3. Создание новых кластеров"

for CLUSTER in freesurf ghostway testbot; do
    case $CLUSTER in
        freesurf) PORT=5432 ;;
        ghostway) PORT=5433 ;;
        testbot) PORT=5434 ;;
    esac
    
    log "Создание кластера $CLUSTER на порту $PORT..."
    pg_createcluster $PG_VERSION $CLUSTER --port $PORT
    check_error "Не удалось создать кластер $CLUSTER"
    
    log "  ${GREEN}✓${NC} Кластер $CLUSTER создан"
done

# ===========================================
# 4. НАСТРОЙКА КОНФИГУРАЦИИ
# ===========================================

print_header "4. Настройка конфигурации"

for CLUSTER in freesurf ghostway testbot; do
    CONF_FILE="/etc/postgresql/$PG_VERSION/$CLUSTER/postgresql.conf"
    HBA_FILE="/etc/postgresql/$PG_VERSION/$CLUSTER/pg_hba.conf"
    
    log "Настройка $CLUSTER..."
    
    # Настройка postgresql.conf - слушаем все интерфейсы
    if grep -q "^listen_addresses" $CONF_FILE 2>/dev/null; then
        sed -i "s/^listen_addresses.*/listen_addresses = '*'/" $CONF_FILE
    else
        sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/" $CONF_FILE
    fi
    
    # Создаем резервную копию pg_hba.conf
    cp $HBA_FILE ${HBA_FILE}.backup 2>/dev/null || true
    
    # Настройка pg_hba.conf
    cat > $HBA_FILE << EOF
# PostgreSQL Client Authentication Configuration File
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# Local connections via Unix socket
local   all             all                                     peer

# Local connections via TCP/IP (IPv4)
host    all             all             127.0.0.1/32            scram-sha-256

# Local connections via TCP/IP (IPv6)
host    all             all             ::1/128                 scram-sha-256

# Allowed external IP addresses
EOF
    
    # Добавляем разрешенные внешние IP
    for IP in "${ALLOWED_IPS[@]}"; do
        echo "host    all             all             $IP/32            md5" >> $HBA_FILE
    done
    
    # Добавляем правило для конкретной базы
    cat >> $HBA_FILE << EOF

# Specific database rules
host    $CLUSTER        $CLUSTER        0.0.0.0/0               md5
EOF
    
    log "  ${GREEN}✓${NC} Конфигурация $CLUSTER настроена"
done

# ===========================================
# 5. ЗАПУСК КЛАСТЕРОВ
# ===========================================

print_header "5. Запуск кластеров"

for CLUSTER in freesurf ghostway testbot; do
    log "Запуск кластера $CLUSTER..."
    pg_ctlcluster $PG_VERSION $CLUSTER start
    sleep 2
    
    # Проверяем, что кластер запустился
    if pg_lsclusters 2>/dev/null | grep -q "$CLUSTER.*online"; then
        log "  ${GREEN}✓${NC} Кластер $CLUSTER запущен"
    else
        log "  ${RED}✗${NC} Ошибка запуска кластера $CLUSTER"
        log "  Логи кластера:"
        tail -20 /var/log/postgresql/postgresql-$PG_VERSION-$CLUSTER.log 2>/dev/null || true
        exit 1
    fi
done

# ===========================================
# 6. НАСТРОЙКА АВТОЗАПУСКА
# ===========================================

print_header "6. Настройка автозапуска кластеров"

# Включаем автозапуск для каждого кластера
for CLUSTER in freesurf ghostway testbot; do
    log "Настройка автозапуска для кластера $CLUSTER..."
    systemctl enable postgresql@${PG_VERSION}-${CLUSTER} 2>/dev/null || true
    log "  ${GREEN}✓${NC} Автозапуск для $CLUSTER настроен"
done

# Включаем общую службу postgresql
systemctl enable postgresql 2>/dev/null || true
log "${GREEN}✓${NC} Автозапуск PostgreSQL настроен"

# ===========================================
# 7. СОЗДАНИЕ ПОЛЬЗОВАТЕЛЕЙ И БАЗ ДАННЫХ (ИСПРАВЛЕННАЯ ВЕРСИЯ)
# ===========================================

print_header "7. Создание пользователей и баз данных"

for CLUSTER in freesurf ghostway testbot; do
    case $CLUSTER in
        freesurf) PORT=5432; USER="freesurf"; PASS="gXGQZ_w44f05_IbKF3bBkAJK99_r2R2C" ;;
        ghostway) PORT=5433; USER="ghostway"; PASS="BHySDRAiYX-bUamciAQsbt3Y70M6PJlI" ;;
        testbot) PORT=5434; USER="testbot"; PASS="ONRx-deA5PHYAfk-Pl7sUt-8lldiX2hn" ;;
    esac
    
    log "Создание базы $CLUSTER (порт $PORT)..."
    
    # Проверяем и создаем пользователя
    USER_EXISTS=$(sudo -u postgres psql -p $PORT -tAc "SELECT 1 FROM pg_user WHERE usename='$USER'" 2>/dev/null)
    if [ "$USER_EXISTS" != "1" ]; then
        sudo -u postgres psql -p $PORT -c "CREATE USER $USER WITH PASSWORD '$PASS';"
        log "  ${GREEN}✓${NC} Пользователь $USER создан"
    else
        log "  Пользователь $USER уже существует"
    fi
    
    # Проверяем и создаем базу данных
    DB_EXISTS=$(sudo -u postgres psql -p $PORT -tAc "SELECT 1 FROM pg_database WHERE datname='$CLUSTER'" 2>/dev/null)
    if [ "$DB_EXISTS" != "1" ]; then
        sudo -u postgres psql -p $PORT -c "CREATE DATABASE $CLUSTER OWNER $USER;"
        log "  ${GREEN}✓${NC} База $CLUSTER создана"
    else
        log "  База $CLUSTER уже существует"
    fi
    
    # Настраиваем права
    sudo -u postgres psql -p $PORT -d $CLUSTER << EOF
-- Настраиваем схему public
GRANT ALL ON SCHEMA public TO $USER;
GRANT CREATE ON SCHEMA public TO $USER;
ALTER SCHEMA public OWNER TO $USER;

-- Настраиваем права на базу
ALTER DATABASE $CLUSTER OWNER TO $USER;
GRANT CONNECT ON DATABASE $CLUSTER TO $USER;

-- Настраиваем права по умолчанию
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO $USER;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO $USER;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON FUNCTIONS TO $USER;
EOF
    
    if [ $? -eq 0 ]; then
        log "  ${GREEN}✓${NC} Права настроены"
    else
        log "  ${RED}✗${NC} Ошибка настройки прав"
    fi
    echo ""
done

# ===========================================
# 8. ПРОВЕРКА РАБОТОСПОСОБНОСТИ
# ===========================================

print_header "8. Проверка работоспособности"

echo ""
echo "Статус кластеров:"
pg_lsclusters 2>/dev/null
echo ""

for CLUSTER in freesurf ghostway testbot; do
    case $CLUSTER in
        freesurf) PORT=5432; PASS="gXGQZ_w44f05_IbKF3bBkAJK99_r2R2C" ;;
        ghostway) PORT=5433; PASS="BHySDRAiYX-bUamciAQsbt3Y70M6PJlI" ;;
        testbot) PORT=5434; PASS="ONRx-deA5PHYAfk-Pl7sUt-8lldiX2hn" ;;
    esac
    
    echo "========================================="
    echo "Проверка $CLUSTER (порт $PORT)"
    echo "========================================="
    
    # Проверяем существование базы
    DB_EXISTS=$(sudo -u postgres psql -p $PORT -tAc "SELECT 1 FROM pg_database WHERE datname='$CLUSTER'" 2>/dev/null)
    if [ "$DB_EXISTS" = "1" ]; then
        echo -e "${GREEN}✓ База $CLUSTER существует${NC}"
    else
        echo -e "${RED}✗ База $CLUSTER не существует${NC}"
    fi
    
    # Проверяем подключение
    if PGPASSWORD=$PASS psql -h localhost -p $PORT -U $CLUSTER -d $CLUSTER -c "SELECT 'OK' as test, current_database(), current_user();" 2>/dev/null; then
        echo -e "${GREEN}✓ Подключение успешно${NC}"
        
        # Получаем размер базы
        DB_SIZE=$(PGPASSWORD=$PASS psql -h localhost -p $PORT -U $CLUSTER -d $CLUSTER -tAc "SELECT pg_database_size('$CLUSTER')/1024 || ' KB'" 2>/dev/null)
        echo "  Размер базы: $DB_SIZE"
    else
        echo -e "${RED}✗ Ошибка подключения${NC}"
    fi
    echo ""
done

# ===========================================
# 9. СОЗДАНИЕ ОТЧЕТА
# ===========================================

print_header "9. Создание отчета"

REPORT_FILE="/root/postgres_setup_report_$(date +%Y%m%d_%H%M%S).txt"

SERVER_IP=$(hostname -I | awk '{print $1}')

cat > "$REPORT_FILE" << EOF
=========================================
ОТЧЕТ О РАЗВЕРТЫВАНИИ POSTGRESQL
=========================================
Дата: $(date)
Сервер: $(hostname)
IP адрес сервера: $SERVER_IP
Версия PostgreSQL: $PG_VERSION

=========================================
КЛАСТЕРЫ, БАЗЫ ДАННЫХ И ПОЛЬЗОВАТЕЛИ
=========================================

freesurf:
  Порт: 5432
  База данных: freesurf
  Пользователь: freesurf
  Пароль: gXGQZ_w44f05_IbKF3bBkAJK99_r2R2C
  
  Строка подключения:
    Локально: PGPASSWORD='gXGQZ_w44f05_IbKF3bBkAJK99_r2R2C' psql -h localhost -p 5432 -U freesurf -d freesurf
    Удаленно: PGPASSWORD='gXGQZ_w44f05_IbKF3bBkAJK99_r2R2C' psql -h $SERVER_IP -p 5432 -U freesurf -d freesurf

ghostway:
  Порт: 5433
  База данных: ghostway
  Пользователь: ghostway
  Пароль: BHySDRAiYX-bUamciAQsbt3Y70M6PJlI
  
  Строка подключения:
    Локально: PGPASSWORD='BHySDRAiYX-bUamciAQsbt3Y70M6PJlI' psql -h localhost -p 5433 -U ghostway -d ghostway
    Удаленно: PGPASSWORD='BHySDRAiYX-bUamciAQsbt3Y70M6PJlI' psql -h $SERVER_IP -p 5433 -U ghostway -d ghostway

testbot:
  Порт: 5434
  База данных: testbot
  Пользователь: testbot
  Пароль: ONRx-deA5PHYAfk-Pl7sUt-8lldiX2hn
  
  Строка подключения:
    Локально: PGPASSWORD='ONRx-deA5PHYAfk-Pl7sUt-8lldiX2hn' psql -h localhost -p 5434 -U testbot -d testbot
    Удаленно: PGPASSWORD='ONRx-deA5PHYAfk-Pl7sUt-8lldiX2hn' psql -h $SERVER_IP -p 5434 -U testbot -d testbot

=========================================
РАЗРЕШЕННЫЕ ВНЕШНИЕ IP АДРЕСА
=========================================

EOF

for IP in "${ALLOWED_IPS[@]}"; do
    echo "  $IP/32 (md5)" >> "$REPORT_FILE"
done

cat >> "$REPORT_FILE" << EOF

=========================================
КОМАНДЫ УПРАВЛЕНИЯ
=========================================

# Просмотр статуса всех кластеров
pg_lsclusters

# Остановка кластера
pg_ctlcluster $PG_VERSION freesurf stop

# Запуск кластера
pg_ctlcluster $PG_VERSION freesurf start

# Перезапуск кластера
pg_ctlcluster $PG_VERSION freesurf restart

# Просмотр логов
tail -f /var/log/postgresql/postgresql-$PG_VERSION-freesurf.log

=========================================
EOF

log "${GREEN}✓${NC} Отчет сохранен: $REPORT_FILE"

# ===========================================
# 10. ФИНАЛЬНЫЙ ВЫВОД
# ===========================================

print_header "РАЗВЕРТЫВАНИЕ УСПЕШНО ЗАВЕРШЕНО!"

echo ""
echo -e "${GREEN}✓ PostgreSQL $PG_VERSION установлен${NC}"
echo -e "${GREEN}✓ 3 кластера созданы и запущены${NC}"
echo -e "${GREEN}✓ Настроен автозапуск всех кластеров${NC}"
echo -e "${GREEN}✓ Пользователи и базы данных созданы${NC}"
echo ""
echo "Статус кластеров:"
pg_lsclusters 2>/dev/null
echo ""
echo "Строки подключения:"
echo "  freesurf: PGPASSWORD='gXGQZ_w44f05_IbKF3bBkAJK99_r2R2C' psql -h localhost -p 5432 -U freesurf -d freesurf"
echo "  ghostway: PGPASSWORD='BHySDRAiYX-bUamciAQsbt3Y70M6PJlI' psql -h localhost -p 5433 -U ghostway -d ghostway"
echo "  testbot:  PGPASSWORD='ONRx-deA5PHYAfk-Pl7sUt-8lldiX2hn' psql -h localhost -p 5434 -U testbot -d testbot"
echo ""
echo "Отчет: $REPORT_FILE"
echo "========================================="

exit 0
