#!/bin/bash

################################################################################
# Enhanced Plex Backup Script with Real-time JSON Metrics
################################################################################
#
# This example shows how to integrate the unified metrics system into the 
# existing Plex backup script with minimal changes while maintaining 
# backward compatibility with the current performance tracking system.
#
# Key Integration Points:
#   1. Initialize metrics at script start
#   2. Update status during key operations
#   3. Track file-by-file progress
#   4. Record performance phases
#   5. Complete session with final status
#
################################################################################

# Load the unified metrics library
source "$(dirname "$(readlink -f "$0")")/lib/unified-backup-metrics.sh"

# Original script variables (unchanged)
BACKUP_ROOT="/mnt/share/media/backups/plex"
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
LOCAL_LOG_ROOT="${SCRIPT_DIR}/logs"
PERFORMANCE_LOG_FILE="${LOCAL_LOG_ROOT}/plex-backup-performance.json"

# Original Plex files configuration (unchanged)
declare -A PLEX_FILES=(
    ["database"]="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db"
    ["blobs"]="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.blobs.db" 
    ["preferences"]="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Preferences.xml"
)

# Colors (unchanged)
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# Original logging functions (unchanged - metrics run in parallel)
log_message() {
    local message="$1"
    local timestamp
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo -e "${BLUE}[${timestamp}]${NC} ${message}"
    mkdir -p "$LOCAL_LOG_ROOT"
    echo "[${timestamp}] $message" >> "${LOCAL_LOG_ROOT}/plex-backup-$(date '+%Y-%m-%d').log" 2>/dev/null || true
}

log_success() {
    local message="$1"
    local timestamp
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo -e "${GREEN}[${timestamp}] SUCCESS:${NC} ${message}"
    mkdir -p "$LOCAL_LOG_ROOT"
    echo "[${timestamp}] SUCCESS: $message" >> "${LOCAL_LOG_ROOT}/plex-backup-$(date '+%Y-%m-%d').log" 2>/dev/null || true
}

log_error() {
    local message="$1"
    local timestamp
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo -e "${RED}[${timestamp}] ERROR:${NC} ${message}"
    mkdir -p "$LOCAL_LOG_ROOT"
    echo "[${timestamp}] ERROR: $message" >> "${LOCAL_LOG_ROOT}/plex-backup-$(date '+%Y-%m-%d').log" 2>/dev/null || true
}

log_warning() {
    local message="$1"
    local timestamp
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo -e "${YELLOW}[${timestamp}] WARNING:${NC} ${message}"
    mkdir -p "$LOCAL_LOG_ROOT"
    echo "[${timestamp}] WARNING: $message" >> "${LOCAL_LOG_ROOT}/plex-backup-$(date '+%Y-%m-%d').log" 2>/dev/null || true
}

# Original performance tracking function (unchanged - metrics system integrates)
track_performance() {
    local operation="$1"
    local start_time="$2"
    local end_time="${3:-$(date +%s)}"
    local duration=$((end_time - start_time))

    # Initialize performance log if it doesn't exist
    if [ ! -f "$PERFORMANCE_LOG_FILE" ]; then
        mkdir -p "$(dirname "$PERFORMANCE_LOG_FILE")"
        echo "[]" > "$PERFORMANCE_LOG_FILE"
    fi

    # Add performance entry
    local entry
    entry=$(jq -n \
        --arg operation "$operation" \
        --arg duration "$duration" \
        --arg timestamp "$(date -Iseconds)" \
        '{
            operation: $operation,
            duration_seconds: ($duration | tonumber),
            timestamp: $timestamp
        }')

    jq --argjson entry "$entry" '. += [$entry]' "$PERFORMANCE_LOG_FILE" > "${PERFORMANCE_LOG_FILE}.tmp" && \
    mv "${PERFORMANCE_LOG_FILE}.tmp" "$PERFORMANCE_LOG_FILE"

    log_message "Performance: $operation completed in ${duration}s"
}

# Enhanced service management with metrics integration
manage_plex_service() {
    local action="$1"
    local operation_start
    operation_start=$(date +%s)

    log_message "Managing Plex service: $action"
    
    # Update metrics status
    metrics_update_status "running" "${action}_service"

    case "$action" in
        stop)
            if sudo systemctl stop plexmediaserver.service; then
                log_success "Plex service stopped"
                
                # Wait for clean shutdown with progress indicator
                local wait_time=0
                local max_wait=15

                while [ $wait_time -lt $max_wait ]; do
                    if ! sudo systemctl is-active --quiet plexmediaserver.service; then
                        log_success "Plex service confirmed stopped (${wait_time}s)"
                        
                        # Track performance in both systems
                        track_performance "service_stop" "$operation_start"
                        metrics_time_phase "service_stop" "$operation_start"
                        
                        return 0
                    fi
                    sleep 1
                    wait_time=$((wait_time + 1))
                    echo -n "."
                done
                echo

                log_warning "Plex service may not have stopped cleanly after ${max_wait}s"
                metrics_warning "Service stop took longer than expected (${max_wait}s)"
                return 1
            else
                log_error "Failed to stop Plex service"
                metrics_error "Failed to stop Plex service"
                return 1
            fi
            ;;
        start)
            if sudo systemctl start plexmediaserver.service; then
                log_success "Plex service start command issued"
                
                # Wait for service to be fully running with progress indicator
                local wait_time=0
                local max_wait=30

                while [ $wait_time -lt $max_wait ]; do
                    if sudo systemctl is-active --quiet plexmediaserver.service; then
                        log_success "Plex service confirmed running (${wait_time}s)"
                        
                        # Track performance in both systems
                        track_performance "service_start" "$operation_start"
                        metrics_time_phase "service_start" "$operation_start"
                        
                        return 0
                    fi
                    sleep 1
                    wait_time=$((wait_time + 1))
                    echo -n "."
                done
                echo

                log_error "Plex service failed to start within ${max_wait}s"
                metrics_error "Service failed to start within ${max_wait}s"
                return 1
            else
                log_error "Failed to start Plex service"
                metrics_error "Failed to start Plex service"
                return 1
            fi
            ;;
        *)
            log_error "Invalid service action: $action"
            metrics_error "Invalid service action: $action"
            return 1
            ;;
    esac
}

# Enhanced backup copy with file-by-file tracking
backup_file_with_metrics() {
    local nickname="$1"
    local source_file="$2"
    local backup_file="$3"
    
    log_message "Backing up $(basename "$source_file")..."
    
    if [ ! -f "$source_file" ]; then
        log_warning "File not found: $source_file"
        metrics_add_file "$source_file" "skipped" "0" "" "File not found"
        return 1
    fi
    
    # Get source file size for metrics
    local file_size
    file_size=$(stat -c%s "$source_file" 2>/dev/null || echo "0")
    
    # Copy file
    if cp "$source_file" "$backup_file"; then
        # Verify the copy
        if [ -f "$backup_file" ]; then
            # Calculate checksum for verification
            local checksum
            checksum=$(md5sum "$backup_file" 2>/dev/null | cut -d' ' -f1 || echo "")
            
            log_success "Backed up: $(basename "$source_file") (${file_size} bytes)"
            metrics_add_file "$source_file" "success" "$file_size" "$checksum"
            return 0
        else
            log_error "Verification failed: $(basename "$source_file")"
            metrics_add_file "$source_file" "failed" "0" "" "Verification failed after copy"
            return 1
        fi
    else
        log_error "Failed to copy: $(basename "$source_file")"
        metrics_add_file "$source_file" "failed" "0" "" "Copy operation failed"
        return 1
    fi
}

# Main backup function with metrics integration
main() {
    local overall_start
    overall_start=$(date +%s)

    log_message "Starting enhanced Plex backup process at $(date)"

    # Initialize metrics system
    local session_id="plex_backup_$(date +%Y%m%d_%H%M%S)"
    if ! metrics_init "plex" "$BACKUP_ROOT" "$session_id"; then
        log_warning "JSON metrics initialization failed, continuing with legacy tracking only"
        local metrics_enabled=false
    else
        local metrics_enabled=true
        log_message "JSON metrics enabled - session: $session_id"
        
        # Set total files count for progress tracking
        metrics_set_total_files "${#PLEX_FILES[@]}" "0"
        
        # Start the backup session
        metrics_start_backup
    fi

    # Create necessary directories
    mkdir -p "${BACKUP_ROOT}"
    mkdir -p "${LOCAL_LOG_ROOT}"

    local backup_errors=0
    local files_backed_up=0
    local backed_up_files=()
    local BACKUP_PATH="${BACKUP_ROOT}"

    # Ensure backup root directory exists
    mkdir -p "$BACKUP_PATH"

    # Update status: stopping service
    if [ "$metrics_enabled" = true ]; then
        metrics_update_status "running" "stopping_service"
    fi

    # Stop Plex service
    if ! manage_plex_service stop; then
        log_error "Failed to stop Plex service, aborting backup"
        if [ "$metrics_enabled" = true ]; then
            metrics_complete_backup "failed" "Failed to stop Plex service"
        fi
        exit 1
    fi

    # Update status: starting backup phase
    if [ "$metrics_enabled" = true ]; then
        metrics_update_status "running" "backing_up_files"
    fi

    # Backup files with individual file tracking
    local backup_phase_start
    backup_phase_start=$(date +%s)

    for nickname in "${!PLEX_FILES[@]}"; do
        local file="${PLEX_FILES[$nickname]}"
        local backup_file="${BACKUP_PATH}/$(basename "$file")"

        if backup_file_with_metrics "$nickname" "$file" "$backup_file"; then
            files_backed_up=$((files_backed_up + 1))
            # Add friendly filename to backed up files list
            case "$(basename "$file")" in
                "com.plexapp.plugins.library.db") backed_up_files+=("library.db") ;;
                "com.plexapp.plugins.library.blobs.db") backed_up_files+=("blobs.db") ;;
                "Preferences.xml") backed_up_files+=("Preferences.xml") ;;
                *) backed_up_files+=("$(basename "$file")") ;;
            esac
        else
            backup_errors=$((backup_errors + 1))
        fi
    done

    # Track backup phase performance
    track_performance "backup" "$backup_phase_start"
    if [ "$metrics_enabled" = true ]; then
        metrics_time_phase "backup" "$backup_phase_start"
    fi

    # Update status: creating archive
    if [ "$metrics_enabled" = true ]; then
        metrics_update_status "running" "creating_archive"
    fi

    # Create archive if files were backed up
    local archive_created=false
    if [ "$files_backed_up" -gt 0 ]; then
        local compression_start
        compression_start=$(date +%s)
        
        local archive_name="plex-backup-$(date +%Y%m%d_%H%M%S).tar.gz"
        local archive_path="${BACKUP_ROOT}/${archive_name}"

        log_message "Creating compressed archive: $archive_name"
        
        if cd "$BACKUP_PATH" && tar -czf "$archive_path" *.db *.xml 2>/dev/null; then
            log_success "Created archive: $archive_name"
            archive_created=true
            
            # Track compression performance
            track_performance "compression" "$compression_start"
            if [ "$metrics_enabled" = true ]; then
                metrics_time_phase "compression" "$compression_start"
            fi

            # Clean up individual files after successful archive creation
            rm -f "$BACKUP_PATH"/*.db "$BACKUP_PATH"/*.xml 2>/dev/null || true
            
            # Get archive information for metrics
            if [ "$metrics_enabled" = true ]; then
                local archive_size
                archive_size=$(stat -c%s "$archive_path" 2>/dev/null || echo "0")
                local archive_checksum
                archive_checksum=$(md5sum "$archive_path" 2>/dev/null | cut -d' ' -f1 || echo "")
                
                metrics_add_file "$archive_path" "success" "$archive_size" "$archive_checksum"
            fi
        else
            log_error "Failed to create archive"
            backup_errors=$((backup_errors + 1))
            if [ "$metrics_enabled" = true ]; then
                metrics_error "Failed to create compressed archive"
            fi
        fi
    fi

    # Update status: starting service
    if [ "$metrics_enabled" = true ]; then
        metrics_update_status "running" "starting_service"
    fi

    # Start Plex service
    manage_plex_service start

    # Update status: cleaning up
    if [ "$metrics_enabled" = true ]; then
        metrics_update_status "running" "cleaning_up"
    fi

    # Cleanup old backups
    local cleanup_start
    cleanup_start=$(date +%s)
    
    log_message "Cleaning up old backups..."
    # [Original cleanup logic here - unchanged]
    
    track_performance "cleanup" "$cleanup_start"
    if [ "$metrics_enabled" = true ]; then
        metrics_time_phase "cleanup" "$cleanup_start"
    fi

    # Track overall backup performance
    track_performance "total_script" "$overall_start"

    # Final summary
    local total_time=$(($(date +%s) - overall_start))
    log_message "Backup process completed at $(date)"
    log_message "Total execution time: ${total_time}s"
    log_message "Files backed up: $files_backed_up"
    log_message "Errors encountered: $backup_errors"

    # Complete metrics session
    if [ "$metrics_enabled" = true ]; then
        local final_status="success"
        local completion_message="Backup completed successfully"
        
        if [ "$backup_errors" -gt 0 ]; then
            final_status="partial"
            completion_message="Backup completed with $backup_errors errors"
        elif [ "$files_backed_up" -eq 0 ]; then
            final_status="failed"
            completion_message="No files were backed up"
        fi
        
        metrics_complete_backup "$final_status" "$completion_message"
        log_message "JSON metrics session completed: $session_id"
    fi

    # Exit with appropriate code
    if [ "$backup_errors" -gt 0 ]; then
        exit 1
    else
        exit 0
    fi
}

# Run main function
main "$@"
