#!/bin/bash

# Скрипт для тестирования baseline миграции на чистой БД
# Создает тестовую БД, применяет baseline, и сравнивает схему с production

set -e

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

# Получаем переменные окружения
DB_HOST=${DB_HOST:-localhost}
DB_PORT=${DB_PORT:-5432}
DB_USER=${DB_USER:-playeng}
DB_PASSWORD=${DB_PASSWORD:-playeng}
DB_NAME=${DB_NAME:-playeng}

TEST_DB_NAME="playeng_baseline_test_$$"
MIGRATIONS_PATH="migrations"
TMP_DIR=$(mktemp -d)

echo "=== Тестирование baseline миграции на чистой БД ==="
echo ""

# Добавляем ~/go/bin в PATH если migrate не найден
if ! command -v migrate &> /dev/null; then
    export PATH="$HOME/go/bin:$PATH"
fi

# Проверяем наличие необходимых инструментов
if ! command -v migrate &> /dev/null; then
    echo -e "${RED}Ошибка: migrate не найден. Установите golang-migrate:${NC}"
    echo "  brew install golang-migrate"
    echo "  или"
    echo "  go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest"
    exit 1
fi

# Определяем способ выполнения PostgreSQL команд
PG_DUMP_CMD=""
PG_PSQL_CMD=""
POSTGRES_CONTAINER=""
if command -v pg_dump &> /dev/null; then
    PG_DUMP_CMD="pg_dump"
    PG_PSQL_CMD="psql"
else
    # Пытаемся найти PostgreSQL контейнер
    if command -v docker &> /dev/null; then
        POSTGRES_CONTAINER=$(docker ps --format "{{.Names}}" 2>/dev/null | grep -iE "(postgres|db)" | head -1)
        if [ -n "$POSTGRES_CONTAINER" ]; then
            PG_DUMP_CMD="docker exec $POSTGRES_CONTAINER pg_dump"
            PG_PSQL_CMD="docker exec -i $POSTGRES_CONTAINER psql"
            echo -e "${BLUE}Используется PostgreSQL из Docker контейнера: $POSTGRES_CONTAINER${NC}"
        fi
    fi
fi

HAS_PG_DUMP=false
if [ -n "$PG_DUMP_CMD" ]; then
    HAS_PG_DUMP=true
else
    echo -e "${YELLOW}Предупреждение: pg_dump не найден. Сравнение схем будет пропущено.${NC}"
    echo "   Для полного тестирования установите PostgreSQL client tools"
fi

# Проверяем наличие директории миграций
if [ ! -d "$MIGRATIONS_PATH" ]; then
    echo -e "${RED}Ошибка: Директория миграций не найдена: $MIGRATIONS_PATH${NC}"
    exit 1
fi

# Проверяем наличие baseline миграции
if [ ! -f "$MIGRATIONS_PATH/000001_baseline.up.sql" ]; then
    echo -e "${RED}Ошибка: Baseline миграция не найдена: $MIGRATIONS_PATH/000001_baseline.up.sql${NC}"
    exit 1
fi

echo "Параметры подключения:"
echo "  Host: $DB_HOST"
echo "  Port: $DB_PORT"
echo "  User: $DB_USER"
echo "  Test DB: $TEST_DB_NAME"
echo ""

# Проверяем подключение к БД
echo "1. Проверка подключения к БД..."
if [ -n "$POSTGRES_CONTAINER" ]; then
    # Используем Docker
    echo "SELECT 1;" | $PG_PSQL_CMD -U $DB_USER -d postgres > /dev/null 2>&1
elif [ -n "$PG_PSQL_CMD" ]; then
    # Используем локальный psql
    PGPASSWORD=$DB_PASSWORD $PG_PSQL_CMD \
        -h $DB_HOST \
        -p $DB_PORT \
        -U $DB_USER \
        -d postgres \
        -c "SELECT 1;" > /dev/null 2>&1
else
    # Пытаемся через стандартный psql
    PGPASSWORD=$DB_PASSWORD psql \
        -h $DB_HOST \
        -p $DB_PORT \
        -U $DB_USER \
        -d postgres \
        -c "SELECT 1;" > /dev/null 2>&1
fi

if [ $? -ne 0 ]; then
    echo -e "${RED}Ошибка: Не удалось подключиться к БД${NC}"
    exit 1
fi

echo -e "${GREEN}✓ Подключение успешно${NC}"
echo ""

# Создаем тестовую БД
echo "2. Создание тестовой БД..."
if [ -n "$POSTGRES_CONTAINER" ]; then
    echo "CREATE DATABASE $TEST_DB_NAME;" | $PG_PSQL_CMD -U $DB_USER -d postgres > /dev/null 2>&1
elif [ -n "$PG_PSQL_CMD" ]; then
    PGPASSWORD=$DB_PASSWORD $PG_PSQL_CMD \
        -h $DB_HOST \
        -p $DB_PORT \
        -U $DB_USER \
        -d postgres \
        -c "CREATE DATABASE $TEST_DB_NAME;" > /dev/null 2>&1
else
    PGPASSWORD=$DB_PASSWORD psql \
        -h $DB_HOST \
        -p $DB_PORT \
        -U $DB_USER \
        -d postgres \
        -c "CREATE DATABASE $TEST_DB_NAME;" > /dev/null 2>&1
fi

if [ $? -ne 0 ]; then
    echo -e "${RED}Ошибка: Не удалось создать тестовую БД${NC}"
    exit 1
fi

echo -e "${GREEN}✓ Тестовая БД создана: $TEST_DB_NAME${NC}"
echo ""

# Ждем немного, чтобы БД точно создалась
sleep 1

# Проверяем, что БД создана
echo "3. Проверка существования тестовой БД..."
if [ -n "$POSTGRES_CONTAINER" ]; then
    if echo "SELECT 1 FROM pg_database WHERE datname='$TEST_DB_NAME';" | $PG_PSQL_CMD -U $DB_USER -d postgres -t | grep -q 1; then
        echo -e "${GREEN}✓ БД подтверждена${NC}"
    else
        echo -e "${RED}Ошибка: БД не найдена после создания${NC}"
        exit 1
    fi
fi
echo ""

# Применяем baseline миграцию
echo "4. Применение baseline миграции..."
cd "$(dirname "$0")" || exit 1

if [ -n "$POSTGRES_CONTAINER" ]; then
    # Для Docker контейнеров используем psql напрямую, так как migrate может иметь проблемы с подключением
    echo -e "${BLUE}Применение миграции через psql (Docker)...${NC}"
    if [ -f "$MIGRATIONS_PATH/000001_baseline.up.sql" ]; then
        if cat "$MIGRATIONS_PATH/000001_baseline.up.sql" | $PG_PSQL_CMD -U $DB_USER -d $TEST_DB_NAME > /dev/null 2>&1; then
            echo -e "${GREEN}✓ Миграция применена через psql${NC}"
            # Создаем таблицу schema_migrations вручную для migrate
            echo "CREATE TABLE IF NOT EXISTS schema_migrations (version bigint NOT NULL PRIMARY KEY, dirty boolean NOT NULL);" | $PG_PSQL_CMD -U $DB_USER -d $TEST_DB_NAME > /dev/null 2>&1
            echo "INSERT INTO schema_migrations (version, dirty) VALUES (1, false) ON CONFLICT (version) DO UPDATE SET dirty = false;" | $PG_PSQL_CMD -U $DB_USER -d $TEST_DB_NAME > /dev/null 2>&1
            MIGRATE_SUCCESS=false  # Устанавливаем в false, чтобы использовать psql для проверки версии
        else
            echo -e "${RED}Ошибка: Не удалось применить миграцию через psql${NC}"
            exit 1
        fi
    else
        echo -e "${RED}Ошибка: Файл миграции не найден${NC}"
        exit 1
    fi
    DATABASE_URL="postgres://$DB_USER:$DB_PASSWORD@localhost:$DB_PORT/$TEST_DB_NAME?sslmode=disable"
else
    DATABASE_URL="postgres://$DB_USER:$DB_PASSWORD@$DB_HOST:$DB_PORT/$TEST_DB_NAME?sslmode=disable"
    if ! migrate -path "$MIGRATIONS_PATH" -database "$DATABASE_URL" up; then
        echo -e "${RED}Ошибка: Не удалось применить baseline миграцию${NC}"
        exit 1
    fi
fi

echo -e "${GREEN}✓ Baseline миграция применена${NC}"
echo ""

# Проверяем версию миграции
echo "5. Проверка версии миграции..."
if [ -n "$POSTGRES_CONTAINER" ] && [ "${MIGRATE_SUCCESS:-false}" = "false" ]; then
    # Проверяем версию через psql
    VERSION=$(echo "SELECT version FROM schema_migrations;" | $PG_PSQL_CMD -U $DB_USER -d $TEST_DB_NAME -t 2>/dev/null | tr -d ' ' | head -1)
    if [ -n "$VERSION" ] && [ "$VERSION" != "" ]; then
        echo "   Версия: $VERSION"
        if [ "$VERSION" = "1" ]; then
            echo -e "${GREEN}✓ Версия миграции корректна${NC}"
        else
            echo -e "${YELLOW}⚠ Неожиданная версия миграции: $VERSION${NC}"
        fi
    else
        echo -e "${YELLOW}⚠ Не удалось определить версию миграции${NC}"
    fi
else
    # Используем migrate для проверки версии
    VERSION=$(migrate -path "$MIGRATIONS_PATH" -database "$DATABASE_URL" version 2>&1)
    echo "   Версия: $VERSION"
    
    if echo "$VERSION" | grep -qE "^1"; then
        echo -e "${GREEN}✓ Версия миграции корректна${NC}"
    else
        echo -e "${YELLOW}⚠ Неожиданная версия миграции${NC}"
    fi
fi
echo ""

# Экспортируем схему из тестовой БД (если pg_dump доступен)
if [ "$HAS_PG_DUMP" = true ]; then
    echo "6. Экспорт схемы из тестовой БД..."
    if [ -n "$POSTGRES_CONTAINER" ]; then
        $PG_DUMP_CMD -U $DB_USER -d $TEST_DB_NAME --schema-only --no-owner --no-privileges > "$TMP_DIR/baseline_schema.sql"
    else
        PGPASSWORD=$DB_PASSWORD $PG_DUMP_CMD \
            -h $DB_HOST \
            -p $DB_PORT \
            -U $DB_USER \
            -d $TEST_DB_NAME \
            --schema-only \
            --no-owner \
            --no-privileges \
            -f "$TMP_DIR/baseline_schema.sql"
    fi

    if [ $? -ne 0 ]; then
        echo -e "${RED}Ошибка: Не удалось экспортировать схему${NC}"
        exit 1
    fi

    echo -e "${GREEN}✓ Схема экспортирована${NC}"
    echo ""

    # Пытаемся экспортировать схему из production БД для сравнения
    echo "7. Экспорт схемы из production БД для сравнения..."
    if [ -n "$POSTGRES_CONTAINER" ]; then
        if $PG_DUMP_CMD -U $DB_USER -d $DB_NAME --schema-only --no-owner --no-privileges > "$TMP_DIR/production_schema.sql" 2>/dev/null; then
            PROD_EXPORT_SUCCESS=true
        else
            PROD_EXPORT_SUCCESS=false
        fi
    else
        if PGPASSWORD=$DB_PASSWORD $PG_DUMP_CMD \
            -h $DB_HOST \
            -p $DB_PORT \
            -U $DB_USER \
            -d $DB_NAME \
            --schema-only \
            --no-owner \
            --no-privileges \
            -f "$TMP_DIR/production_schema.sql" 2>/dev/null; then
            PROD_EXPORT_SUCCESS=true
        else
            PROD_EXPORT_SUCCESS=false
        fi
    fi
    
    if [ "$PROD_EXPORT_SUCCESS" = true ]; then
    
    echo -e "${GREEN}✓ Схема production экспортирована${NC}"
    echo ""
    
    # Сравниваем схемы
    echo "8. Сравнение схем..."
    
    # Подсчитываем объекты
    echo -e "${BLUE}Таблицы:${NC}"
    BASELINE_TABLES=$(grep -c "CREATE TABLE" "$TMP_DIR/baseline_schema.sql" || echo "0")
    PROD_TABLES=$(grep -c "CREATE TABLE" "$TMP_DIR/production_schema.sql" || echo "0")
    echo "   Baseline:  $BASELINE_TABLES"
    echo "   Production: $PROD_TABLES"
    
    if [ "$BASELINE_TABLES" -eq "$PROD_TABLES" ]; then
        echo -e "   ${GREEN}✓ Количество таблиц совпадает${NC}"
    else
        echo -e "   ${YELLOW}⚠ Количество таблиц не совпадает${NC}"
    fi
    
    echo ""
    echo -e "${BLUE}Индексы:${NC}"
    BASELINE_INDEXES=$(grep -c "CREATE.*INDEX" "$TMP_DIR/baseline_schema.sql" || echo "0")
    PROD_INDEXES=$(grep -c "CREATE.*INDEX" "$TMP_DIR/production_schema.sql" || echo "0")
    echo "   Baseline:  $BASELINE_INDEXES"
    echo "   Production: $PROD_INDEXES"
    
    if [ "$BASELINE_INDEXES" -eq "$PROD_INDEXES" ]; then
        echo -e "   ${GREEN}✓ Количество индексов совпадает${NC}"
    else
        echo -e "   ${YELLOW}⚠ Количество индексов не совпадает${NC}"
    fi
    
    echo ""
    echo -e "${BLUE}Materialized Views:${NC}"
    BASELINE_MV=$(grep -c "CREATE MATERIALIZED VIEW" "$TMP_DIR/baseline_schema.sql" || echo "0")
    PROD_MV=$(grep -c "CREATE MATERIALIZED VIEW" "$TMP_DIR/production_schema.sql" || echo "0")
    echo "   Baseline:  $BASELINE_MV"
    echo "   Production: $PROD_MV"
    
    if [ "$BASELINE_MV" -eq "$PROD_MV" ]; then
        echo -e "   ${GREEN}✓ Количество materialized views совпадает${NC}"
    else
        echo -e "   ${YELLOW}⚠ Количество materialized views не совпадает${NC}"
    fi
    
        echo ""
        echo "Для детального сравнения выполните:"
        echo "  diff $TMP_DIR/baseline_schema.sql $TMP_DIR/production_schema.sql"
        echo ""
        echo "Или используйте:"
        echo "  diff -u $TMP_DIR/baseline_schema.sql $TMP_DIR/production_schema.sql | less"
        
    else
        echo -e "${YELLOW}⚠ Не удалось экспортировать схему production БД${NC}"
        echo "   Продолжаем без сравнения"
        echo ""
        echo "Схема baseline сохранена в: $TMP_DIR/baseline_schema.sql"
    fi
else
    echo "6. Пропуск экспорта схемы (pg_dump недоступен)"
    echo ""
    echo -e "${YELLOW}Для полного тестирования установите PostgreSQL client tools:${NC}"
    echo "  macOS: brew install postgresql"
    echo "  или используйте Docker контейнер с PostgreSQL"
    echo ""
fi

echo ""
echo "=== Тестирование завершено ==="
echo ""
echo -e "${GREEN}✓ Baseline миграция успешно применена к чистой БД${NC}"
echo ""
