#!/bin/bash

# FTP Diagnostic Script for WHP ProFTPD Issues
# This script helps diagnose FTP connection and passive mode issues

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

# Function to print colored output
print_status() {
    local status=$1
    local message=$2
    case $status in
        "OK")
            echo -e "${GREEN}✓${NC} $message"
            ;;
        "WARN")
            echo -e "${YELLOW}⚠${NC} $message"
            ;;
        "ERROR")
            echo -e "${RED}✗${NC} $message"
            ;;
        "INFO")
            echo -e "${BLUE}ℹ${NC} $message"
            ;;
    esac
}

# Function to check if running as root
check_root() {
    if [[ $EUID -ne 0 ]]; then
        print_status "ERROR" "This script must be run as root"
        exit 1
    fi
}

# Function to check ProFTPD service status
check_proftpd_status() {
    print_status "INFO" "Checking ProFTPD service status..."
    
    if systemctl is-active --quiet proftpd; then
        print_status "OK" "ProFTPD service is running"
        
        # Show service details
        echo "Service details:"
        systemctl status proftpd --no-pager -l | head -10
    else
        print_status "ERROR" "ProFTPD service is not running"
        
        # Show service details
        echo "Service status:"
        systemctl status proftpd --no-pager -l | head -10
        
        # Show recent logs
        echo ""
        print_status "INFO" "Recent ProFTPD logs:"
        journalctl -u proftpd --no-pager -n 10
        
        return 1
    fi
}

# Function to check network configuration
check_network_config() {
    print_status "INFO" "Checking network configuration..."
    
    echo "Network interfaces:"
    ip addr show | grep -E "inet.*global|inet.*host"
    
    echo ""
    echo "Default route:"
    ip route | grep default
    
    echo ""
    echo "Active network connections on FTP ports:"
    netstat -tlnp | grep -E ":21|:60[0-9][0-9][0-9]"
}

# Function to check ProFTPD configuration
check_proftpd_config() {
    print_status "INFO" "Checking ProFTPD configuration..."
    
    local config_file="/etc/proftpd/proftpd.conf"
    
    if [[ ! -f "$config_file" ]]; then
        print_status "ERROR" "ProFTPD configuration file not found: $config_file"
        return 1
    fi
    
    # Check configuration syntax
    print_status "INFO" "Testing configuration syntax..."
    if proftpd -t; then
        print_status "OK" "Configuration syntax is valid"
    else
        print_status "ERROR" "Configuration syntax errors found"
        return 1
    fi
    
    # Show key configuration settings
    echo ""
    print_status "INFO" "Key configuration settings:"
    
    echo "Passive mode settings:"
    grep -E "PassivePorts|MasqueradeAddress" "$config_file" || echo "  No passive mode settings found"
    
    echo ""
    echo "MySQL connection settings:"
    grep -E "SQLConnectInfo" "$config_file" || echo "  No MySQL connection settings found"
    
    echo ""
    echo "Authentication settings:"
    grep -E "SQLAuthenticate|SQLUserInfo" "$config_file" || echo "  No SQL authentication settings found"
}

# Function to check firewall configuration
check_firewall_config() {
    print_status "INFO" "Checking firewall configuration..."
    
    echo "Active firewall zones:"
    firewall-cmd --get-active-zones
    
    echo ""
    echo "Allowed FTP ports:"
    firewall-cmd --list-ports | grep -E "21|60[0-9][0-9][0-9]" || echo "  No FTP ports found in firewall rules"
    
    echo ""
    echo "FTP service in firewall:"
    firewall-cmd --list-services | grep ftp || echo "  FTP service not enabled in firewall"
    
    # Check if ports are actually listening
    echo ""
    print_status "INFO" "Checking listening ports:"
    
    if netstat -tlnp | grep -q ":21"; then
        print_status "OK" "Port 21 (FTP control) is listening"
        netstat -tlnp | grep ":21"
    else
        print_status "ERROR" "Port 21 (FTP control) is not listening"
    fi
    
    local passive_ports_listening=$(netstat -tlnp | grep -E ":60[0-9][0-9][0-9]" | wc -l)
    if [[ $passive_ports_listening -gt 0 ]]; then
        print_status "WARN" "Some passive ports are already in use ($passive_ports_listening ports)"
        echo "Passive ports in use:"
        netstat -tlnp | grep -E ":60[0-9][0-9][0-9]" | head -5
    else
        print_status "OK" "Passive port range 60000-60100 appears to be available"
    fi
}

# Function to check MySQL connectivity
check_mysql_connectivity() {
    print_status "INFO" "Checking MySQL connectivity for ProFTPD..."
    
    # Get MySQL config
    if [[ -f /root/.my.cnf ]]; then
        local mysql_password=$(grep -E "^password=" /root/.my.cnf | cut -d'=' -f2)
        
        # Test root connection
        if mysql -h localhost -u root -p"$mysql_password" -e "SELECT 1;" >/dev/null 2>&1; then
            print_status "OK" "MySQL root connection successful"
            
            # Check if FTP tables exist
            local ftp_tables=$(mysql -h localhost -u root -p"$mysql_password" -D whp -se "SHOW TABLES LIKE 'ftp_%';" | wc -l)
            if [[ $ftp_tables -gt 0 ]]; then
                print_status "OK" "FTP tables found in database ($ftp_tables tables)"
                echo "FTP tables:"
                mysql -h localhost -u root -p"$mysql_password" -D whp -se "SHOW TABLES LIKE 'ftp_%';"
            else
                print_status "ERROR" "No FTP tables found in database"
            fi
            
            # Check FTP user in database
            local ftp_users_count=$(mysql -h localhost -u root -p"$mysql_password" -D whp -se "SELECT COUNT(*) FROM ftp_users;" 2>/dev/null || echo "0")
            if [[ $ftp_users_count -gt 0 ]]; then
                print_status "OK" "FTP users found in database ($ftp_users_count users)"
                echo "FTP users:"
                mysql -h localhost -u root -p"$mysql_password" -D whp -se "SELECT username, uid, gid, homedir FROM ftp_users;"
            else
                print_status "WARN" "No FTP users found in database"
            fi
            
        else
            print_status "ERROR" "Cannot connect to MySQL database"
        fi
    else
        print_status "ERROR" "MySQL configuration file not found: /root/.my.cnf"
    fi
}

# Function to test FTP connection locally
test_local_ftp() {
    print_status "INFO" "Testing local FTP connection..."
    
    # Test control connection
    if timeout 5 bash -c "</dev/tcp/localhost/21"; then
        print_status "OK" "FTP control port (21) is accessible"
    else
        print_status "ERROR" "Cannot connect to FTP control port (21)"
        return 1
    fi
    
    # Test passive port range
    local test_port=60000
    if timeout 5 bash -c "</dev/tcp/localhost/$test_port" 2>/dev/null; then
        print_status "WARN" "Passive port $test_port is already in use"
    else
        print_status "OK" "Passive port $test_port is available"
    fi
}

# Function to show recent FTP logs
show_recent_logs() {
    print_status "INFO" "Recent FTP connection logs..."
    
    echo "ProFTPD system logs (last 10 lines):"
    if [[ -f /var/log/proftpd/system.log ]]; then
        tail -10 /var/log/proftpd/system.log
    else
        echo "  System log file not found"
    fi
    
    echo ""
    echo "ProFTPD transfer logs (last 10 lines):"
    if [[ -f /var/log/proftpd/transfer.log ]]; then
        tail -10 /var/log/proftpd/transfer.log
    else
        echo "  Transfer log file not found"
    fi
    
    echo ""
    echo "Systemd journal for ProFTPD (last 10 lines):"
    journalctl -u proftpd --no-pager -n 10
}

# Function to show configuration recommendations
show_recommendations() {
    print_status "INFO" "Configuration recommendations..."
    
    echo "For passive mode issues:"
    echo "1. Ensure MasqueradeAddress is set to your server's external IP"
    echo "2. Verify firewall allows passive port range 60000-60100"
    echo "3. Check NAT/router configuration if behind firewall"
    echo ""
    echo "For authentication issues:"
    echo "1. Verify MySQL connection in ProFTPD config"
    echo "2. Check FTP user exists in database"
    echo "3. Verify user home directory exists and has correct permissions"
    echo ""
    echo "Useful commands:"
    echo "- systemctl restart proftpd"
    echo "- /root/whp/scripts/proftpd-helper.sh status"
    echo "- /root/whp/scripts/proftpd-helper.sh show username"
    echo "- firewall-cmd --reload"
}

# Main diagnostic function
main() {
    check_root
    
    echo "ProFTPD Diagnostic Report"
    echo "========================"
    echo ""
    
    check_proftpd_status
    echo ""
    
    check_network_config
    echo ""
    
    check_proftpd_config
    echo ""
    
    check_firewall_config
    echo ""
    
    check_mysql_connectivity
    echo ""
    
    test_local_ftp
    echo ""
    
    show_recent_logs
    echo ""
    
    show_recommendations
}

# Run main function
main "$@" 