#!/bin/bash

# Database Management Script
# Handles backup and restore operations for both SQLite (frontend) and PostgreSQL (backend)

set -e  # Exit on any error

# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BACKEND_DIR="$SCRIPT_DIR/legalconsenthub-backend"
FRONTEND_DIR="$SCRIPT_DIR/legalconsenthub"

# Database files
SQLITE_DB="$FRONTEND_DIR/sqlite.db"
SQLITE_BACKUP="$FRONTEND_DIR/sqlite-backup.db"
POSTGRES_BACKUP="$BACKEND_DIR/src/main/resources/legalconsenthub-db-backup.sql"

# PostgreSQL connection details
POSTGRES_HOST="localhost"
POSTGRES_PORT="5432"
POSTGRES_DB="legalconsenthub"
POSTGRES_USER="legalconsenthub"
POSTGRES_PASSWORD="legalconsenthub"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Helper functions
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Check if PostgreSQL container is running
check_postgres() {
    # Check if the legalconsenthub-backend container is running
    if docker ps --format "table {{.Names}}\t{{.Status}}" | grep -q "legalconsenthub-backend.*Up"; then
        # Additional check to see if the database is ready
        if docker exec legalconsenthub-backend pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB" &>/dev/null; then
            return 0
        fi
    fi
    return 1
}

# Check if PostgreSQL container exists and is running
ensure_postgres_running() {
    if ! check_postgres; then
        log_error "PostgreSQL container 'legalconsenthub-backend' is not running."
        log_error "Please start the container before running backup/restore operations."
        exit 1
    fi
}

# Create backup of current SQLite database
backup_sqlite() {
    log_info "Creating SQLite backup..."
    if [ -f "$SQLITE_DB" ]; then
        cp "$SQLITE_DB" "$SQLITE_BACKUP"
        log_success "SQLite backup created: $SQLITE_BACKUP"
    else
        log_warning "SQLite database not found: $SQLITE_DB"
    fi
}

# Create backup of current PostgreSQL database
backup_postgres() {
    log_info "Creating PostgreSQL backup..."
    ensure_postgres_running
    
    # Create temporary backup file
    local temp_backup="${POSTGRES_BACKUP}.tmp"
    
    # Generate backup with pg_dump
    docker exec legalconsenthub-backend pg_dump \
        -U "$POSTGRES_USER" \
        -d "$POSTGRES_DB" \
        --no-owner \
        --no-privileges \
        --clean \
        --if-exists \
        > "$temp_backup"
    
    # Add force DROP statements at the beginning
    {
        echo "--"
        echo "-- PostgreSQL database dump"
        echo "--"
        echo ""
        echo "--"
        echo "-- Force drop all tables and constraints to ensure clean restoration"
        echo "--"
        echo ""
        echo "DROP TABLE IF EXISTS public.user_organization_roles CASCADE;"
        echo "DROP TABLE IF EXISTS public.notification CASCADE;"
        echo "DROP TABLE IF EXISTS public.form_element_section CASCADE;"
        echo "DROP TABLE IF EXISTS public.form_element_options CASCADE;"
        echo "DROP TABLE IF EXISTS public.form_element CASCADE;"
        echo "DROP TABLE IF EXISTS public.comment CASCADE;"
        echo "DROP TABLE IF EXISTS public.application_form CASCADE;"
        echo "DROP TABLE IF EXISTS public.app_user CASCADE;"
        echo "DROP TABLE IF EXISTS public.databasechangeloglock CASCADE;"
        echo "DROP TABLE IF EXISTS public.databasechangelog CASCADE;"
        echo ""
        echo "-- Drop any remaining sequences, views, or other objects"
        echo "DROP SEQUENCE IF EXISTS public.hibernate_sequence CASCADE;"
        echo ""
        echo "-- Reset database configuration"
        
        # Skip the first few lines of the original dump (headers) and append the rest
        tail -n +4 "$temp_backup"
    } > "$POSTGRES_BACKUP"
    
    # Remove temporary file
    rm "$temp_backup"
    
    log_success "PostgreSQL backup created with force DROP statements: $POSTGRES_BACKUP"
}

# Restore SQLite database from backup
restore_sqlite() {
    log_info "Restoring SQLite database from backup..."
    if [ -f "$SQLITE_BACKUP" ]; then
        # Remove current database if it exists
        if [ -f "$SQLITE_DB" ]; then
            rm "$SQLITE_DB"
            log_info "Removed current SQLite database"
        fi
        
        # Copy backup to current database
        cp "$SQLITE_BACKUP" "$SQLITE_DB"
        log_success "SQLite database restored from: $SQLITE_BACKUP"
    else
        log_error "SQLite backup not found: $SQLITE_BACKUP"
        exit 1
    fi
}

# Restore PostgreSQL database from backup
restore_postgres() {
    log_info "Restoring PostgreSQL database from backup..."
    
    if [ ! -f "$POSTGRES_BACKUP" ]; then
        log_error "PostgreSQL backup not found: $POSTGRES_BACKUP"
        exit 1
    fi
    
    ensure_postgres_running
    
    # Terminate all connections and drop/recreate database
    log_info "Terminating all connections to PostgreSQL database..."
    docker exec legalconsenthub-backend psql \
        -U "$POSTGRES_USER" \
        -d "postgres" \
        -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '$POSTGRES_DB' AND pid <> pg_backend_pid();"
    
    log_info "Dropping and recreating PostgreSQL database..."
    docker exec legalconsenthub-backend psql \
        -U "$POSTGRES_USER" \
        -d "postgres" \
        -c "DROP DATABASE IF EXISTS $POSTGRES_DB;"
    
    docker exec legalconsenthub-backend psql \
        -U "$POSTGRES_USER" \
        -d "postgres" \
        -c "CREATE DATABASE $POSTGRES_DB OWNER $POSTGRES_USER;"
    
    # Restore from backup
    log_info "Restoring database from backup file..."
    docker exec -i legalconsenthub-backend psql \
        -U "$POSTGRES_USER" \
        -d "$POSTGRES_DB" \
        < "$POSTGRES_BACKUP"
    
    log_success "PostgreSQL database restored from: $POSTGRES_BACKUP"
}

# Show usage information
show_usage() {
    echo "Database Management Script"
    echo ""
    echo "Usage: $0 [COMMAND]"
    echo ""
    echo "Commands:"
    echo "  backup          Create backups of current databases"
    echo "  restore         Restore databases from backups"
    echo "  backup-sqlite   Create backup of SQLite database only"
    echo "  backup-postgres Create backup of PostgreSQL database only"
    echo "  restore-sqlite  Restore SQLite database from backup only"
    echo "  restore-postgres Restore PostgreSQL database from backup only"
    echo "  status          Show current status"
    echo "  help            Show this help message"
    echo ""
    echo "Note: PostgreSQL operations require the 'legalconsenthub-backend' container to be running."
    echo ""
    echo "Examples:"
    echo "  $0 backup          # Create backups of both databases"
    echo "  $0 restore         # Restore both databases from backups"
    echo "  $0 backup-sqlite   # Backup only SQLite database"
    echo "  $0 status          # Check database status"
}

# Show current status
show_status() {
    log_info "Database Status:"
    echo ""
    
    # SQLite status
    echo "SQLite Database:"
    if [ -f "$SQLITE_DB" ]; then
        local size=$(du -h "$SQLITE_DB" | cut -f1)
        local modified=$(stat -c "%y" "$SQLITE_DB" 2>/dev/null || stat -f "%Sm" "$SQLITE_DB" 2>/dev/null || echo "Unknown")
        echo "  Current DB: ✅ $SQLITE_DB ($size, modified: $modified)"
    else
        echo "  Current DB: ❌ Not found"
    fi
    
    if [ -f "$SQLITE_BACKUP" ]; then
        local backup_size=$(du -h "$SQLITE_BACKUP" | cut -f1)
        local backup_modified=$(stat -c "%y" "$SQLITE_BACKUP" 2>/dev/null || stat -f "%Sm" "$SQLITE_BACKUP" 2>/dev/null || echo "Unknown")
        echo "  Backup:     ✅ $SQLITE_BACKUP ($backup_size, modified: $backup_modified)"
    else
        echo "  Backup:     ❌ Not found"
    fi
    
    echo ""
    
    # PostgreSQL status
    echo "PostgreSQL Database:"
    if check_postgres; then
        echo "  Container:  ✅ legalconsenthub-backend (Running)"
        local db_size=$(docker exec legalconsenthub-backend psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -t -c "SELECT pg_size_pretty(pg_database_size('$POSTGRES_DB'));" 2>/dev/null | xargs || echo "Unknown")
        echo "  Database:   ✅ $POSTGRES_DB ($db_size)"
    else
        echo "  Container:  ❌ legalconsenthub-backend (Not running or not found)"
        echo "  Database:   ❓ Cannot check (container not available)"
    fi
    
    if [ -f "$POSTGRES_BACKUP" ]; then
        local backup_size=$(du -h "$POSTGRES_BACKUP" | cut -f1)
        local backup_modified=$(stat -c "%y" "$POSTGRES_BACKUP" 2>/dev/null || stat -f "%Sm" "$POSTGRES_BACKUP" 2>/dev/null || echo "Unknown")
        echo "  Backup:     ✅ $POSTGRES_BACKUP ($backup_size, modified: $backup_modified)"
    else
        echo "  Backup:     ❌ Not found"
    fi
}

# Main script logic
main() {
    case "${1:-help}" in
        "backup")
            log_info "Creating backups of both databases..."
            backup_sqlite
            backup_postgres
            log_success "All backups completed successfully!"
            ;;
        "restore")
            log_info "Restoring both databases from backups..."
            restore_sqlite
            restore_postgres
            log_success "All databases restored successfully!"
            ;;
        "backup-sqlite")
            backup_sqlite
            ;;
        "backup-postgres")
            backup_postgres
            ;;
        "restore-sqlite")
            restore_sqlite
            ;;
        "restore-postgres")
            restore_postgres
            ;;
        "status")
            show_status
            ;;
        "help"|"-h"|"--help")
            show_usage
            ;;
        *)
            log_error "Unknown command: $1"
            echo ""
            show_usage
            exit 1
            ;;
    esac
}

# Check for required tools
check_dependencies() {
    local missing_tools=()
    
    # Check for Docker
    if ! command -v docker &> /dev/null; then
        missing_tools+=("docker")
    fi
    
    if [ ${#missing_tools[@]} -gt 0 ]; then
        log_error "Missing required tools:"
        for tool in "${missing_tools[@]}"; do
            echo "  - $tool"
        done
        echo ""
        echo "Please install the missing tools and try again."
        exit 1
    fi
}

# Run dependency check and main function
check_dependencies
main "$@"
