#!/bin/bash
#
# Torrent Mover Configuration Utility
# A helper tool to safely update and manage your torrent-mover configuration

set -e

CONFIG_PATH="/etc/torrent/mover.conf"
BACKUP_DIR="/etc/torrent/backups"
DEFAULT_EDITOR="${EDITOR:-nano}"

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

print_header() {
    echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
    echo -e "${BLUE}║                Torrent Mover Config Utility                ║${NC}"
    echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}"
    echo ""
}

usage() {
    print_header
    echo -e "Usage: ${GREEN}$(basename "$0")${NC} [OPTION]"
    echo ""
    echo "Options:"
    echo -e "  ${YELLOW}edit${NC}            Edit the configuration file with your default editor"
    echo -e "  ${YELLOW}backup${NC}          Create a backup of the current configuration"
    echo -e "  ${YELLOW}restore${NC} [file]  Restore a previous backup (lists available backups if no file specified)"
    echo -e "  ${YELLOW}validate${NC}        Check the configuration for errors"
    echo -e "  ${YELLOW}default${NC}         Show the default configuration values"
    echo -e "  ${YELLOW}show${NC}            Display the current configuration"
    echo -e "  ${YELLOW}set${NC} key value   Update a specific configuration value"
    echo -e "  ${YELLOW}get${NC} key         Get the value of a specific configuration key"
    echo -e "  ${YELLOW}help${NC}            Display this help message"
    echo ""
    echo "Examples:"
    echo "  $(basename "$0") edit             # Edit the configuration file"
    echo "  $(basename "$0") backup           # Create a timestamped backup"
    echo "  $(basename "$0") set COPY_MODE move  # Change the copy mode to 'move'"
    echo "  $(basename "$0") get TRANSMISSION_IP # Show the Transmission server IP"
    echo ""
}

# Check if user is root or using sudo
check_permissions() {
    if [ "$EUID" -ne 0 ]; then
        echo -e "${RED}Error: This command requires root privileges.${NC}"
        echo "Please run with sudo:"
        echo -e "  ${YELLOW}sudo $(basename "$0") $*${NC}"
        exit 1
    fi
}

# Create a backup of the current configuration
backup_config() {
    check_permissions "$@"
    
    if [ ! -f "$CONFIG_PATH" ]; then
        echo -e "${RED}Error: Configuration file not found at $CONFIG_PATH${NC}"
        exit 1
    fi
    
    mkdir -p "$BACKUP_DIR"
    local timestamp=$(date +"%Y%m%d_%H%M%S")
    local backup_file="$BACKUP_DIR/mover.conf.$timestamp"
    
    cp "$CONFIG_PATH" "$backup_file"
    echo -e "${GREEN}Configuration backed up to:${NC} $backup_file"
}

# Restore a configuration from backup
restore_config() {
    check_permissions "$@"
    
    if [ ! -d "$BACKUP_DIR" ]; then
        echo -e "${RED}Error: Backup directory not found at $BACKUP_DIR${NC}"
        exit 1
    fi
    
    if [ -z "$1" ]; then
        # List available backups
        echo -e "${BLUE}Available backups:${NC}"
        local count=0
        for file in "$BACKUP_DIR"/mover.conf.*; do
            if [ -f "$file" ]; then
                count=$((count+1))
                local date_part=$(basename "$file" | cut -d. -f3)
                echo -e "${YELLOW}$count)${NC} $(basename "$file") ($(date -d "${date_part:0:8} ${date_part:9:2}:${date_part:11:2}:${date_part:13:2}" "+%Y-%m-%d %H:%M:%S"))"
            fi
        done
        
        if [ "$count" -eq 0 ]; then
            echo -e "${YELLOW}No backups found.${NC}"
            exit 0
        fi
        
        echo ""
        read -p "Enter the number of the backup to restore: " selection
        
        if ! [[ "$selection" =~ ^[0-9]+$ ]] || [ "$selection" -lt 1 ] || [ "$selection" -gt "$count" ]; then
            echo -e "${RED}Error: Invalid selection.${NC}"
            exit 1
        fi
        
        # Get the filename of the selected backup
        local selected_file=$(ls -1 "$BACKUP_DIR"/mover.conf.* | sed -n "${selection}p")
    else
        # Use the specified backup file
        local selected_file="$BACKUP_DIR/$1"
        
        if [ ! -f "$selected_file" ]; then
            echo -e "${RED}Error: Backup file not found at $selected_file${NC}"
            exit 1
        fi
    fi
    
    # Create a backup of the current config before restoring
    backup_config
    
    # Restore the selected backup
    cp "$selected_file" "$CONFIG_PATH"
    echo -e "${GREEN}Configuration restored from:${NC} $selected_file"
}

# Edit the configuration file
edit_config() {
    check_permissions "$@"
    
    if [ ! -f "$CONFIG_PATH" ]; then
        echo -e "${RED}Error: Configuration file not found at $CONFIG_PATH${NC}"
        exit 1
    fi
    
    # Create a backup before editing
    backup_config
    
    # Open in the user's preferred editor
    $DEFAULT_EDITOR "$CONFIG_PATH"
    
    # Validate after editing
    validate_config
}

# Validate the configuration for errors
validate_config() {
    check_permissions "$@"
    
    if [ ! -f "$CONFIG_PATH" ]; then
        echo -e "${RED}Error: Configuration file not found at $CONFIG_PATH${NC}"
        exit 1
    fi
    
    echo -e "${BLUE}Validating configuration file...${NC}"
    
    # Source the config file in a subshell to check for syntax errors
    if ! (bash -n "$CONFIG_PATH"); then
        echo -e "${RED}Error: The configuration file contains syntax errors.${NC}"
        exit 1
    fi
    
    # Load the configuration
    source "$CONFIG_PATH"
    
    # Check mandatory settings
    local required_vars=(
        "TRANSMISSION_IP"
        "TRANSMISSION_PORT"
        "TRANSMISSION_PATH_PREFIX"
        "LOCAL_PATH_PREFIX"
        "DIR_MOVIES_DST"
        "DIR_APPS_DST"
        "DIR_GAMES_DST"
        "DIR_BOOKS_DST"
        "DEFAULT_DST"
        "COPY_MODE"
    )
    
    local error_count=0
    for var in "${required_vars[@]}"; do
        if [ -z "${!var}" ]; then
            echo -e "${RED}Error: Required setting '$var' is not defined.${NC}"
            error_count=$((error_count+1))
        fi
    done
    
    # Validate COPY_MODE
    if [ -n "$COPY_MODE" ] && [ "$COPY_MODE" != "copy" ] && [ "$COPY_MODE" != "move" ]; then
        echo -e "${RED}Error: COPY_MODE must be 'copy' or 'move', not '$COPY_MODE'.${NC}"
        error_count=$((error_count+1))
    fi
    
    # Validate directory paths
    local dir_vars=(
        "DIR_GAMES_DST"
        "DIR_APPS_DST"
        "DIR_MOVIES_DST"
        "DIR_BOOKS_DST"
        "DIR_TV_DST"
        "DIR_MUSIC_DST"
        "DEFAULT_DST"
    )
    
    for var in "${dir_vars[@]}"; do
        if [ -n "${!var}" ]; then
            if [[ ! "${!var}" == /* ]]; then
                echo -e "${RED}Error: Directory path for '$var' must be absolute (start with /).${NC}"
                error_count=$((error_count+1))
            fi
        fi
    done
    
    # Check if any pattern in CUSTOM_PATTERNS references undefined variables
    if [ -n "$CUSTOM_PATTERNS" ]; then
        IFS=';' read -ra PATTERN_ARRAY <<< "$CUSTOM_PATTERNS"
        for pattern in "${PATTERN_ARRAY[@]}"; do
            IFS='=' read -ra PARTS <<< "$pattern"
            if [ "${#PARTS[@]}" -eq 2 ]; then
                local dest="${PARTS[1]}"
                if [[ "$dest" == *'${'*'}'* ]]; then
                    local var_name=$(echo "$dest" | sed -n 's/.*\${//;s/}.*//p')
                    if [ -z "${!var_name}" ]; then
                        echo -e "${RED}Error: Custom pattern uses undefined variable: \${$var_name}${NC}"
                        error_count=$((error_count+1))
                    fi
                fi
            fi
        done
    fi
    
    if [ "$error_count" -eq 0 ]; then
        echo -e "${GREEN}Configuration validation passed. No errors found.${NC}"
    else
        echo -e "${RED}Configuration validation failed with $error_count error(s).${NC}"
        exit 1
    fi
}

# Show the current configuration
show_config() {
    if [ ! -f "$CONFIG_PATH" ]; then
        echo -e "${RED}Error: Configuration file not found at $CONFIG_PATH${NC}"
        exit 1
    fi
    
    print_header
    echo -e "${BLUE}Current Configuration:${NC}"
    echo ""
    
    # Load config and display it categorized
    source "$CONFIG_PATH"
    
    echo -e "${YELLOW}=== Connection Settings ===${NC}"
    echo -e "TRANSMISSION_IP=${GREEN}${TRANSMISSION_IP:-<not set>}${NC}"
    echo -e "TRANSMISSION_PORT=${GREEN}${TRANSMISSION_PORT:-<not set>}${NC}"
    if [ -n "$TRANSMISSION_USER" ]; then
        echo -e "TRANSMISSION_USER=${GREEN}${TRANSMISSION_USER}${NC}"
        echo -e "TRANSMISSION_PASSWORD=${GREEN}********${NC}"
    else
        echo -e "TRANSMISSION_USER=${YELLOW}<not set>${NC}"
        echo -e "TRANSMISSION_PASSWORD=${YELLOW}<not set>${NC}"
    fi
    echo -e "TRANSMISSION_PATH_PREFIX=${GREEN}${TRANSMISSION_PATH_PREFIX:-<not set>}${NC}"
    echo -e "LOCAL_PATH_PREFIX=${GREEN}${LOCAL_PATH_PREFIX:-<not set>}${NC}"
    echo ""
    
    echo -e "${YELLOW}=== Destination Directories ===${NC}"
    echo -e "DIR_GAMES_DST=${GREEN}${DIR_GAMES_DST:-<not set>}${NC}"
    echo -e "DIR_APPS_DST=${GREEN}${DIR_APPS_DST:-<not set>}${NC}"
    echo -e "DIR_MOVIES_DST=${GREEN}${DIR_MOVIES_DST:-<not set>}${NC}"
    echo -e "DIR_BOOKS_DST=${GREEN}${DIR_BOOKS_DST:-<not set>}${NC}"
    echo -e "DIR_TV_DST=${GREEN}${DIR_TV_DST:-<not set>}${NC}"
    echo -e "DIR_MUSIC_DST=${GREEN}${DIR_MUSIC_DST:-<not set>}${NC}"
    echo -e "DEFAULT_DST=${GREEN}${DEFAULT_DST:-<not set>}${NC}"
    echo ""
    
    echo -e "${YELLOW}=== Additional Storage Libraries ===${NC}"
    echo -e "STORAGE_DIRS=${GREEN}${STORAGE_DIRS:-<not set>}${NC}"
    echo -e "STORAGE_TV_DIRS=${GREEN}${STORAGE_TV_DIRS:-<not set>}${NC}"
    echo ""
    
    echo -e "${YELLOW}=== Security Settings ===${NC}"
    echo -e "TORRENT_USER=${GREEN}${TORRENT_USER:-debian-transmission}${NC}"
    echo -e "TORRENT_GROUP=${GREEN}${TORRENT_GROUP:-debian-transmission}${NC}"
    echo ""
    
    echo -e "${YELLOW}=== Performance Settings ===${NC}"
    echo -e "PARALLEL_THREADS=${GREEN}${PARALLEL_THREADS:-$(nproc)}${NC}"
    echo -e "PARALLEL_PROCESSING=${GREEN}${PARALLEL_PROCESSING:-1}${NC}"
    echo -e "COPY_MODE=${GREEN}${COPY_MODE:-<not set>}${NC}"
    echo ""
    
    echo -e "${YELLOW}=== Error Recovery ===${NC}"
    echo -e "MAX_RETRY_ATTEMPTS=${GREEN}${MAX_RETRY_ATTEMPTS:-3}${NC}"
    echo -e "RETRY_WAIT_TIME=${GREEN}${RETRY_WAIT_TIME:-15}${NC}"
    echo ""
    
    echo -e "${YELLOW}=== Logging & Integrity ===${NC}"
    echo -e "LOG_FILE=${GREEN}${LOG_FILE:-/var/log/torrent_mover.log}${NC}"
    echo -e "LOG_LEVEL=${GREEN}${LOG_LEVEL:-INFO}${NC}"
    echo -e "USE_SYSLOG=${GREEN}${USE_SYSLOG:-false}${NC}"
    echo -e "PROCESSED_LOG=${GREEN}${PROCESSED_LOG:-/var/log/torrent_processed.log}${NC}"
    echo -e "CHECKSUM_DB=${GREEN}${CHECKSUM_DB:-/var/lib/torrent/checksums.db}${NC}"
    echo -e "CHECK_TRANSFER_INTEGRITY=${GREEN}${CHECK_TRANSFER_INTEGRITY:-true}${NC}"
    echo ""
    
    if [ -n "$CUSTOM_PATTERNS" ]; then
        echo -e "${YELLOW}=== Custom Content Patterns ===${NC}"
        IFS=';' read -ra PATTERN_ARRAY <<< "$CUSTOM_PATTERNS"
        for pattern in "${PATTERN_ARRAY[@]}"; do
            if [ -n "$pattern" ]; then
                IFS='=' read -ra PARTS <<< "$pattern"
                if [ "${#PARTS[@]}" -eq 2 ]; then
                    local regex="${PARTS[0]}"
                    local dest="${PARTS[1]}"
                    echo -e "Pattern: ${GREEN}${regex}${NC} → ${BLUE}${dest}${NC}"
                fi
            fi
        done
        echo ""
    fi
}

# Update a specific configuration value
set_config_value() {
    check_permissions "$@"
    
    if [ -z "$1" ] || [ -z "$2" ]; then
        echo -e "${RED}Error: Both key and value must be provided.${NC}"
        echo "Usage: $(basename "$0") set KEY VALUE"
        exit 1
    fi
    
    local key="$1"
    local value="$2"
    
    if [ ! -f "$CONFIG_PATH" ]; then
        echo -e "${RED}Error: Configuration file not found at $CONFIG_PATH${NC}"
        exit 1
    fi
    
    # Create a backup before modifying
    backup_config
    
    # Check if the key already exists in the config
    if grep -q "^$key=" "$CONFIG_PATH"; then
        # Update the existing key
        sed -i "s|^$key=.*|$key=\"$value\"|" "$CONFIG_PATH"
        echo -e "${GREEN}Updated configuration:${NC} $key = \"$value\""
    else
        # Add the new key
        echo "$key=\"$value\"" >> "$CONFIG_PATH"
        echo -e "${GREEN}Added new configuration:${NC} $key = \"$value\""
    fi
    
    # Validate after updating
    validate_config
}

# Get a specific configuration value
get_config_value() {
    if [ -z "$1" ]; then
        echo -e "${RED}Error: Key must be provided.${NC}"
        echo "Usage: $(basename "$0") get KEY"
        exit 1
    fi
    
    local key="$1"
    
    if [ ! -f "$CONFIG_PATH" ]; then
        echo -e "${RED}Error: Configuration file not found at $CONFIG_PATH${NC}"
        exit 1
    fi
    
    # Source the config file to get the value
    source "$CONFIG_PATH"
    
    if [ -n "${!key+x}" ]; then
        echo -e "${key}=${GREEN}${!key}${NC}"
    else
        echo -e "${RED}Error: Configuration key '$key' is not defined.${NC}"
        exit 1
    fi
}

# Show default configuration options
show_default_config() {
    print_header
    echo -e "${BLUE}Default Configuration Values:${NC}"
    echo ""
    cat << EOF
# Transmission Settings
TRANSMISSION_IP="192.168.1.100"
TRANSMISSION_PORT="9091"
TRANSMISSION_USER=""
TRANSMISSION_PASSWORD=""

# Path Mapping
TRANSMISSION_PATH_PREFIX="/downloads"
LOCAL_PATH_PREFIX="/mnt/data"

# Destination Directories
DIR_GAMES_DST="/mnt/media/Games"
DIR_APPS_DST="/mnt/media/Apps"
DIR_MOVIES_DST="/mnt/media/Movies"
DIR_BOOKS_DST="/mnt/media/Books"
DIR_TV_DST="/mnt/media/TV"
DIR_MUSIC_DST="/mnt/media/Music"
DEFAULT_DST="/mnt/media/Other"

# Additional Storage
STORAGE_DIRS=""
STORAGE_TV_DIRS=""

# Security
TORRENT_USER="torrent-mover"
TORRENT_GROUP="torrent-mover"

# Error Recovery
MAX_RETRY_ATTEMPTS="3"
RETRY_WAIT_TIME="15"

# Performance
PARALLEL_THREADS="$(nproc)"
PARALLEL_PROCESSING="1"
COPY_MODE="copy"

# Logging & Integrity
LOG_FILE="/var/log/torrent_mover.log"
LOG_LEVEL="INFO"
USE_SYSLOG="false"
PROCESSED_LOG="/var/log/torrent_processed.log"
CHECKSUM_DB="/var/lib/torrent/checksums.db"
CHECK_TRANSFER_INTEGRITY="true"

# Custom Content Patterns
CUSTOM_PATTERNS=".*documentary.*=\${DIR_MOVIES_DST}/Documentary;.*anime.*=\${DIR_TV_DST}/Anime"
EOF
    echo ""
}

# Main command processing
case "$1" in
    edit)
        edit_config "${@:2}"
        ;;
    backup)
        backup_config "${@:2}"
        ;;
    restore)
        restore_config "${@:2}"
        ;;
    validate)
        validate_config "${@:2}"
        ;;
    show)
        show_config
        ;;
    set)
        set_config_value "${@:2}"
        ;;
    get)
        get_config_value "${@:2}"
        ;;
    default)
        show_default_config
        ;;
    help|--help|-h)
        usage
        ;;
    *)
        usage
        exit 1
        ;;
esac

exit 0