#!/bin/bash

################################################################################
# Plex Recovery Validation Script
################################################################################
#
# Author: Peter Wood <peter@peterwood.dev>
# Description: Comprehensive validation script that verifies the success of
#              Plex database recovery operations. Performs extensive checks
#              on database integrity, service functionality, and system health
#              to ensure complete recovery and operational readiness.
#
# Features:
#   - Database integrity verification
#   - Service functionality testing
#   - Library accessibility checks
#   - Performance validation
#   - Web interface connectivity testing
#   - Comprehensive recovery reporting
#   - Post-recovery optimization suggestions
#
# Related Scripts:
#   - recover-plex-database.sh: Primary recovery script validated by this tool
#   - icu-aware-recovery.sh: ICU recovery validation
#   - nuclear-plex-recovery.sh: Nuclear recovery validation
#   - backup-plex.sh: Backup system that enables recovery
#   - validate-plex-backups.sh: Backup validation tools
#   - plex.sh: General Plex service management
#
# Usage:
#   ./validate-plex-recovery.sh                # Full validation suite
#   ./validate-plex-recovery.sh --quick        # Quick validation checks
#   ./validate-plex-recovery.sh --detailed     # Detailed analysis and reporting
#   ./validate-plex-recovery.sh --performance  # Performance validation only
#
# Dependencies:
#   - sqlite3 or Plex SQLite binary
#   - curl (for web interface testing)
#   - systemctl (for service status checks)
#   - Plex Media Server
#
# Exit Codes:
#   0 - Recovery validation successful
#   1 - General error
#   2 - Database validation failures
#   3 - Service functionality issues
#   4 - Performance concerns detected
#   5 - Partial recovery (requires attention)
#
################################################################################

# Final Plex Recovery Validation Script
# Comprehensive check to ensure Plex is fully recovered and functional

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

PLEX_DB_DIR="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases"

print_status() {
    local color="$1"
    local message="$2"
    echo -e "${color}${message}${NC}"
}

print_header() {
    echo
    print_status "$BLUE" "================================"
    print_status "$BLUE" "$1"
    print_status "$BLUE" "================================"
}

# Check service status
check_service_status() {
    print_header "SERVICE STATUS CHECK"

    if systemctl is-active --quiet plexmediaserver; then
        print_status "$GREEN" "✓ Plex Media Server is running"

        # Get service uptime
        local uptime
        uptime=$(systemctl show plexmediaserver --property=ActiveEnterTimestamp --value)
        print_status "$GREEN" "  Started: $uptime"

        # Get memory usage
        local memory
        memory=$(systemctl show plexmediaserver --property=MemoryCurrent --value)
        if [[ -n "$memory" && "$memory" != "[not set]" ]]; then
            local memory_mb=$((memory / 1024 / 1024))
            print_status "$GREEN" "  Memory usage: ${memory_mb}MB"
        fi

        return 0
    else
        print_status "$RED" "✗ Plex Media Server is not running"
        return 1
    fi
}

# Check database integrity
check_database_integrity() {
    print_header "DATABASE INTEGRITY CHECK"

    local main_db="${PLEX_DB_DIR}/com.plexapp.plugins.library.db"
    local blobs_db="${PLEX_DB_DIR}/com.plexapp.plugins.library.blobs.db"
    local all_good=true

    # Check main database
    if [[ -f "$main_db" ]]; then
        local main_size
        main_size=$(du -h "$main_db" | cut -f1)
        print_status "$GREEN" "✓ Main database exists (${main_size})"

        # Try basic database operations
        if sqlite3 "$main_db" "SELECT COUNT(*) FROM sqlite_master WHERE type='table';" >/dev/null 2>&1; then
            local table_count
            table_count=$(sqlite3 "$main_db" "SELECT COUNT(*) FROM sqlite_master WHERE type='table';" 2>/dev/null)
            print_status "$GREEN" "  Contains $table_count tables"
        else
            print_status "$YELLOW" "  Warning: Cannot query database tables"
            all_good=false
        fi
    else
        print_status "$RED" "✗ Main database missing"
        all_good=false
    fi

    # Check blobs database
    if [[ -f "$blobs_db" ]]; then
        local blobs_size
        blobs_size=$(du -h "$blobs_db" | cut -f1)
        print_status "$GREEN" "✓ Blobs database exists (${blobs_size})"

        # Check if it's not empty (previous corruption was 0 bytes)
        local blobs_bytes
        blobs_bytes=$(stat -c%s "$blobs_db" 2>/dev/null || stat -f%z "$blobs_db" 2>/dev/null)
        if [[ $blobs_bytes -gt 1000000 ]]; then
            print_status "$GREEN" "  File size is healthy ($(numfmt --to=iec "$blobs_bytes"))"
        else
            print_status "$RED" "  Warning: File size is too small ($blobs_bytes bytes)"
            all_good=false
        fi
    else
        print_status "$RED" "✗ Blobs database missing"
        all_good=false
    fi

    # Check file ownership
    local main_owner
    main_owner=$(stat -c%U:%G "$main_db" 2>/dev/null)
    local blobs_owner
    blobs_owner=$(stat -c%U:%G "$blobs_db" 2>/dev/null)

    if [[ "$main_owner" == "plex:plex" && "$blobs_owner" == "plex:plex" ]]; then
        print_status "$GREEN" "✓ Database ownership is correct (plex:plex)"
    else
        print_status "$YELLOW" "  Warning: Ownership issues detected"
        print_status "$YELLOW" "    Main DB: $main_owner, Blobs DB: $blobs_owner"
    fi

    if [[ "$all_good" == "true" ]]; then
        return 0
    else
        return 1
    fi
}

# Check web interface
check_web_interface() {
    print_header "WEB INTERFACE CHECK"

    local max_attempts=5
    local attempt=1

    while [[ $attempt -le $max_attempts ]]; do
        if curl -s -o /dev/null -w "%{http_code}" "http://localhost:32400/web/index.html" | grep -q "200"; then
            print_status "$GREEN" "✓ Web interface is accessible"
            print_status "$GREEN" "  URL: http://localhost:32400"
            return 0
        fi

        print_status "$YELLOW" "  Attempt $attempt/$max_attempts: Web interface not ready..."
        sleep 2
        ((attempt++))
    done

    print_status "$RED" "✗ Web interface is not accessible"
    return 1
}

# Check API functionality
check_api_functionality() {
    print_header "API FUNCTIONALITY CHECK"

    # Test root API endpoint
    local api_response
    api_response=$(curl -s "http://localhost:32400/" 2>/dev/null)

    if echo "$api_response" | grep -q "Unauthorized\|web/index.html"; then
        print_status "$GREEN" "✓ API is responding (redirect to web interface)"
    else
        print_status "$YELLOW" "  Warning: Unexpected API response"
    fi

    # Try to get server identity (this might work without auth)
    local identity_response
    identity_response=$(curl -s "http://localhost:32400/identity" 2>/dev/null)

    if echo "$identity_response" | grep -q "MediaContainer"; then
        print_status "$GREEN" "✓ Server identity endpoint working"
    else
        print_status "$YELLOW" "  Note: Server identity requires authentication"
    fi
}

# Check recent logs for errors
check_recent_logs() {
    print_header "RECENT LOGS CHECK"

    # Check for recent errors in systemd logs
    local recent_errors=$(sudo journalctl -u plexmediaserver --since "5 minutes ago" --no-pager -q 2>/dev/null | grep -i "error\|fail\|exception" | head -3)

    if [[ -z "$recent_errors" ]]; then
        print_status "$GREEN" "✓ No recent errors in service logs"
    else
        print_status "$YELLOW" "  Recent log entries found:"
        echo "$recent_errors" | while read -r line; do
            print_status "$YELLOW" "    $line"
        done
    fi
}

# Show recovery summary
show_recovery_summary() {
    print_header "RECOVERY SUMMARY"

    local corrupted_backup_dir="${PLEX_DB_DIR}/corrupted-20250605_060232"
    if [[ -d "$corrupted_backup_dir" ]]; then
        print_status "$GREEN" "✓ Corrupted databases backed up to:"
        print_status "$GREEN" "  $corrupted_backup_dir"
    fi

    print_status "$GREEN" "✓ Databases restored from: 2025-06-02 backups"
    print_status "$GREEN" "✓ File ownership corrected to plex:plex"
    print_status "$GREEN" "✓ Service restarted successfully"

    echo
    print_status "$BLUE" "NEXT STEPS:"
    print_status "$YELLOW" "1. Access Plex at: http://localhost:32400"
    print_status "$YELLOW" "2. Verify your libraries are intact"
    print_status "$YELLOW" "3. Consider running a library scan to pick up recent changes"
    print_status "$YELLOW" "4. Monitor the service for a few days to ensure stability"
}

# Main function
main() {
    print_status "$BLUE" "PLEX RECOVERY VALIDATION"
    print_status "$BLUE" "$(date)"
    echo

    local overall_status=0

    check_service_status || overall_status=1
    check_database_integrity || overall_status=1
    check_web_interface || overall_status=1
    check_api_functionality
    check_recent_logs
    show_recovery_summary

    echo
    if [[ $overall_status -eq 0 ]]; then
        print_status "$GREEN" "🎉 RECOVERY SUCCESSFUL! Plex Media Server is fully functional."
    else
        print_status "$YELLOW" "⚠️  RECOVERY PARTIALLY SUCCESSFUL - Some issues detected."
        print_status "$YELLOW" "   Plex is running but may need additional attention."
    fi

    return $overall_status
}

# Run the validation
main "$@"
