#!/bin/bash

################################################################################
# Email Functions Library
################################################################################
# Shared functions for email troubleshooting modules
################################################################################

# Source system detection (for detect_control_panel function)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ -f "$SCRIPT_DIR/system-detect.sh" ]; then
    source "$SCRIPT_DIR/system-detect.sh"
fi

# Detect MTA (Mail Transfer Agent)
detect_mta() {
    if command -v exim &>/dev/null; then
        echo "exim"
    elif command -v postfix &>/dev/null || [ -f /etc/postfix/main.cf ]; then
        echo "postfix"
    elif command -v sendmail &>/dev/null; then
        echo "sendmail"
    else
        echo "unknown"
    fi
}

# Get mail log path based on system
get_mail_log_path() {
    local control_panel=$(detect_control_panel 2>/dev/null || echo "unknown")

    # Try common log locations in order of likelihood
    if [ "$control_panel" = "cpanel" ]; then
        if [ -f /var/log/exim_mainlog ]; then
            echo "/var/log/exim_mainlog"
        elif [ -f /var/log/exim/mainlog ]; then
            echo "/var/log/exim/mainlog"
        fi
    elif [ "$control_panel" = "plesk" ]; then
        if [ -f /var/log/maillog ]; then
            echo "/var/log/maillog"
        fi
    else
        # Standalone or other
        if [ -f /var/log/mail.log ]; then
            echo "/var/log/mail.log"
        elif [ -f /var/log/maillog ]; then
            echo "/var/log/maillog"
        elif [ -f /var/log/exim_mainlog ]; then
            echo "/var/log/exim_mainlog"
        fi
    fi
}

# Get mailbox base path
get_mailbox_base_path() {
    local control_panel=$(detect_control_panel 2>/dev/null || echo "unknown")

    case "$control_panel" in
        cpanel)
            echo "/home"
            ;;
        plesk)
            echo "/var/qmail/mailnames"
            ;;
        *)
            # Try common locations
            if [ -d /home/vmail ]; then
                echo "/home/vmail"
            elif [ -d /var/mail ]; then
                echo "/var/mail"
            else
                echo "/home"
            fi
            ;;
    esac
}

# Validate email address format
validate_email() {
    local email="$1"
    if [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
        return 0
    else
        return 1
    fi
}

# Extract domain from email address
get_email_domain() {
    local email="$1"
    echo "${email##*@}"
}

# Extract local part from email address
get_email_local() {
    local email="$1"
    echo "${email%%@*}"
}

# Convert bytes to human-readable format
format_size() {
    local bytes="$1"

    if [ "$bytes" -lt 1024 ]; then
        echo "${bytes}B"
    elif [ "$bytes" -lt 1048576 ]; then
        echo "$((bytes / 1024))KB"
    elif [ "$bytes" -lt 1073741824 ]; then
        echo "$((bytes / 1048576))MB"
    else
        echo "$((bytes / 1073741824))GB"
    fi
}

# Check if MTA service is running
check_mta_running() {
    local mta=$(detect_mta)

    case "$mta" in
        exim)
            if systemctl is-active --quiet exim 2>/dev/null || service exim status &>/dev/null; then
                return 0
            fi
            ;;
        postfix)
            if systemctl is-active --quiet postfix 2>/dev/null || service postfix status &>/dev/null; then
                return 0
            fi
            ;;
        sendmail)
            if systemctl is-active --quiet sendmail 2>/dev/null || service sendmail status &>/dev/null; then
                return 0
            fi
            ;;
    esac

    return 1
}

# Get MTA version
get_mta_version() {
    local mta=$(detect_mta)

    case "$mta" in
        exim)
            exim -bV 2>/dev/null | head -1 | awk '{print $3}'
            ;;
        postfix)
            postconf mail_version 2>/dev/null | awk '{print $3}'
            ;;
        sendmail)
            sendmail -d0.1 2>&1 | head -1 | awk '{print $2}'
            ;;
        *)
            echo "unknown"
            ;;
    esac
}

# Get mail queue count
get_queue_count() {
    local mta=$(detect_mta)

    case "$mta" in
        exim)
            exim -bpc 2>/dev/null || echo "0"
            ;;
        postfix)
            postqueue -p 2>/dev/null | tail -1 | awk '{print $5}' | tr -d '(' | tr -d ')'
            ;;
        *)
            echo "0"
            ;;
    esac
}

# Check DNS record
check_dns_record() {
    local domain="$1"
    local record_type="$2"  # A, MX, TXT, etc.

    if command -v dig &>/dev/null; then
        dig +short "$domain" "$record_type" 2>/dev/null
    elif command -v host &>/dev/null; then
        host -t "$record_type" "$domain" 2>/dev/null | grep -v "has no" | awk '{print $NF}'
    elif command -v nslookup &>/dev/null; then
        nslookup -type="$record_type" "$domain" 2>/dev/null | grep -A10 "answer:" | grep -v "answer:"
    fi
}

# Get server's primary IP
get_primary_ip() {
    # Try multiple methods
    local ip=""

    # Method 1: hostname -i
    ip=$(hostname -I 2>/dev/null | awk '{print $1}')

    # Method 2: ip route
    if [ -z "$ip" ]; then
        ip=$(ip route get 8.8.8.8 2>/dev/null | awk '{print $7; exit}')
    fi

    # Method 3: ifconfig
    if [ -z "$ip" ]; then
        ip=$(ifconfig 2>/dev/null | grep 'inet ' | grep -v '127.0.0.1' | head -1 | awk '{print $2}' | cut -d: -f2)
    fi

    echo "$ip"
}

# Check if IP is valid format
is_valid_ip() {
    local ip="$1"
    if [[ "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        return 0
    else
        return 1
    fi
}

# Get reverse DNS (PTR) for IP
get_reverse_dns() {
    local ip="$1"

    if command -v dig &>/dev/null; then
        dig +short -x "$ip" 2>/dev/null | sed 's/\.$//'
    elif command -v host &>/dev/null; then
        host "$ip" 2>/dev/null | grep "pointer" | awk '{print $NF}' | sed 's/\.$//'
    fi
}

# Send test email
send_test_email() {
    local to="$1"
    local subject="${2:-Test Email from Server Toolkit}"
    local body="${3:-This is a test email sent from the Server Toolkit.}"
    local from="${4:-root@$(hostname)}"

    if command -v mail &>/dev/null; then
        echo "$body" | mail -s "$subject" -r "$from" "$to"
        return $?
    elif command -v sendmail &>/dev/null; then
        {
            echo "From: $from"
            echo "To: $to"
            echo "Subject: $subject"
            echo ""
            echo "$body"
        } | sendmail -t
        return $?
    else
        return 1
    fi
}

# Parse email from Exim log line
parse_exim_email() {
    local log_line="$1"
    # Extract email addresses from various Exim log formats
    echo "$log_line" | grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' | head -1
}

# Get date range for log analysis (default: last 24 hours)
get_log_date_range() {
    local hours="${1:-24}"
    date -d "$hours hours ago" "+%Y-%m-%d %H:%M:%S"
}

# Count messages by sender
count_by_sender() {
    local log_file="$1"
    local min_date="${2:-}"

    if [ -n "$min_date" ]; then
        awk -v min_date="$min_date" '$0 >= min_date' -- "$log_file" | \
            grep "<=" | \
            grep -oE '\<[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\>' | \
            sort | uniq -c | sort -rn
    else
        grep "<=" -- "$log_file" | \
            grep -oE '\<[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\>' | \
            sort | uniq -c | sort -rn
    fi
}

# Export to detect_control_panel if not already available
if ! type detect_control_panel &>/dev/null; then
    detect_control_panel() {
        if [ -f /usr/local/cpanel/version ]; then
            echo "cpanel"
        elif [ -f /usr/local/psa/version ]; then
            echo "plesk"
        else
            echo "standalone"
        fi
    }
fi

# Export functions for use in subshells
export -f detect_mta
export -f get_mail_log_path
export -f get_mailbox_base_path
export -f validate_email
export -f get_email_domain
export -f get_email_local
export -f format_size
export -f check_mta_running
export -f get_mta_version
export -f get_queue_count
export -f check_dns_record
export -f get_primary_ip
export -f is_valid_ip
export -f get_reverse_dns
export -f send_test_email
export -f parse_exim_email
export -f get_log_date_range
export -f count_by_sender
