#!/bin/bash

# --------------------------
# Configuration Variables
# --------------------------
ROOT_DIR="Nmap"

# Default concurrency settings
MAX_PORT_PROCESSES=5       # Maximum concurrent port scan processes
MAX_SERVICE_PROCESSES=5    # Maximum concurrent service scan processes
MAX_LIVE_HOST_PROCESSES=5  # Maximum concurrent live host discovery processes

# Default values for options
RUN_LIVE_HOST=false
RUN_PORT_SCAN=false
RUN_SERVICE_SCAN=false
RUN_CUSTOM_NMAP=false      # For running custom Nmap commands via --nmap-args
RUN_REPORT=false
RUN_HTML_REPORT=false
TARGETS=()
TARGET_FILE=""
USE_EXISTING=false
SCAN_TOP_PORTS=false       # For --top option
EXCLUDE_HOSTS=()
EXCLUDE_PORTS=""
MIN_RATE=""
MAX_RATE=""
NMAP_ADDITIONAL_ARGS=""     # For custom Nmap arguments
VERBOSITY=1                 # Verbosity level (0: silent, 1: normal, 2: verbose)

# Log file
LOG_FILE="$ROOT_DIR/script.log"

# Define ANSI color codes for terminal output
RED='\e[31m'
GREEN='\e[32m'
YELLOW='\e[33m'
MAGENTA='\e[35m'
CYAN='\e[36m'
BLUE='\e[34m'
RESET='\e[0m'

# --------------------------
# Function to display help
# --------------------------
display_help() {
    echo -e "${CYAN}Usage: sudo $0 [options]${RESET}"
    echo
    echo "Options:"
    echo "  -l, --live-host                Run live host discovery scans"
    echo "  -p, --port-scan                Run port scans"
    echo "  -s, --service-scan             Run service scans"
    echo "  -r, --report                   Generate color-coded text report"
    echo "  -H, --html-report              Generate HTML report"
    echo "  -e, --existing                 Use existing live_hosts.txt without requiring targets"
    echo "  -t, --target <IP/subnet>       Specify target IP or subnet (can be used multiple times)"
    echo "  -f, --target-file <file>       Specify file with list of targets"
    echo "      --top                      Scan top 1000 ports instead of all ports"
    echo "  -x, --exclude <IP>             Exclude specific IP from scans (can be used multiple times)"
    echo "  -X, --exclude-ports <ports>    Exclude specific ports from scans (comma-separated)"
    echo "      --min-rate <rate>          Set the minimum rate (packets per second)"
    echo "      --max-rate <rate>          Set the maximum rate (packets per second)"
    echo "  -M, --max-port-processes <n>   Set maximum concurrent port scan processes (default: 5)"
    echo "  -S, --max-service-processes <n>Set maximum concurrent service scan processes (default: 5)"
    echo "      --nmap-args <args>         Additional Nmap arguments"
    echo "      --verbosity <level>        Set verbosity level (0: silent, 1: normal, 2: verbose)"
    echo "  -c, --cleanup                  Remove all scan results"
    echo "  -h, --help                     Display this help message"
    echo
    echo "Examples:"
    echo "  sudo $0 -l -p -s -r -H -f targets.txt"
    echo "  sudo $0 --port-scan --top --existing"
    echo "  sudo $0 --max-port-processes 10 --max-service-processes 8 -p -t 10.0.0.1/24"
    echo "  sudo $0 -p -s -f targets.txt"
    echo "  sudo $0 -r"
    echo "  sudo $0 -H"
    echo "  sudo $0 --nmap-args \"-A -p 80,443\" -t 192.168.1.0/24"
    echo
    echo "Note:"
    echo "  Ensure you have permission to scan the specified IP addresses or subnets."
    exit 0
}

# --------------------------
# Function to log messages
# --------------------------
log_message() {
    local level="$1"
    local message="$2"
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') [$level] $message" | tee -a "$LOG_FILE"
}

# --------------------------
# Function to validate IP addresses and subnets
# --------------------------
validate_target() {
    local target="$1"
    if [[ "$target" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] ||
       [[ "$target" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$ ]] ||
       [[ "$target" =~ ^([a-zA-Z0-9\.\-]+)$ ]]; then
        return 0
    else
        echo -e "${RED}Invalid target format: $target${RESET}" >&2
        exit 1
    fi
}

# --------------------------
# Function to load targets from file or arguments
# --------------------------
load_targets() {
    # If a target file is provided, read targets from the file
    if [ -n "$TARGET_FILE" ]; then
        if [ ! -f "$TARGET_FILE" ]; then
            echo -e "${RED}Error: Target file '$TARGET_FILE' does not exist.${RESET}" >&2
            exit 1
        fi
        while IFS= read -r line; do
            # Ignore empty lines and comments
            if [[ -n "$line" && ! "$line" =~ ^# ]]; then
                validate_target "$line"
                TARGETS+=("$line")
            fi
        done < "$TARGET_FILE"
    fi

    # Check that at least one target is specified
    if [ ${#TARGETS[@]} -eq 0 ] && [ "$USE_EXISTING" = false ] && [ "$RUN_CUSTOM_NMAP" = false ]; then
        echo -e "${RED}Error: No targets specified. Use -t <IP or subnet> or -f <filename>${RESET}" >&2
        exit 1
    fi
}

# --------------------------
# Function to check if the script is run as root
# --------------------------
check_root() {
    if [[ $EUID -ne 0 ]]; then
        echo -e "${RED}Please run this script as root.${RESET}" >&2
        exit 1
    fi
}

# --------------------------
# Function to prepare directories
# --------------------------
prepare_directories() {
    mkdir -p "$ROOT_DIR/Live_Host"
    mkdir -p "$ROOT_DIR/Ports/tcp"
    mkdir -p "$ROOT_DIR/Ports/udp"
    mkdir -p "$ROOT_DIR/Services/tcp"
    mkdir -p "$ROOT_DIR/Services/udp"
}

# --------------------------
# Function to handle concurrency
# --------------------------
sem() {
    local max="$1"
    while (( $(jobs -rp | wc -l) >= max )); do
        sleep 0.1
    done
}

# --------------------------
# Function to run custom Nmap scan
# --------------------------
run_custom_nmap_scan() {
    echo -e "${GREEN}Starting custom Nmap scans...${RESET}"
    log_message "INFO" "Starting custom Nmap scans..."

    # Determine if targets are provided via -t or -f
    if [ ${#TARGETS[@]} -gt 0 ]; then
        # Run Nmap on specified targets with the provided args
        for TARGET in "${TARGETS[@]}"; do
            sem "$MAX_PORT_PROCESSES"
            (
                echo -e "${BLUE}Running custom Nmap scan on target: $TARGET${RESET}"
                log_message "INFO" "Running custom Nmap scan on target: $TARGET"

                # Sanitize target for filenames
                SANITIZED_TARGET=$(echo "$TARGET" | tr '/.' '_')

                # Build the Nmap command
                nmap_cmd=(nmap $NMAP_ADDITIONAL_ARGS -oA "$ROOT_DIR/custom_nmap_${SANITIZED_TARGET}" "$TARGET")

                echo -e "${GREEN}Running: ${nmap_cmd[*]}${RESET}"
                log_message "INFO" "Running: ${nmap_cmd[*]}"
                "${nmap_cmd[@]}"
            ) &
        done
        wait
    else
        # No targets provided via -t or -f, run Nmap with the given args as is
        sem "$MAX_PORT_PROCESSES"
        (
            echo -e "${BLUE}Running custom Nmap scan with arguments: $NMAP_ADDITIONAL_ARGS${RESET}"
            log_message "INFO" "Running custom Nmap scan with arguments: $NMAP_ADDITIONAL_ARGS"

            # Build the Nmap command
            nmap_cmd=(nmap $NMAP_ADDITIONAL_ARGS)

            echo -e "${GREEN}Running: ${nmap_cmd[*]}${RESET}"
            log_message "INFO" "Running: ${nmap_cmd[*]}"
            "${nmap_cmd[@]}"
        ) &
        wait
    fi

    echo -e "${GREEN}Custom Nmap scans completed.${RESET}"
    log_message "INFO" "Custom Nmap scans completed."
}

# --------------------------
# Function to run live host discovery scans
# --------------------------
run_live_host_scans() {
    echo -e "${GREEN}Starting live host discovery scans...${RESET}"
    log_message "INFO" "Starting live host discovery scans..."

    # Load targets
    load_targets

    if [ ${#TARGETS[@]} -eq 0 ]; then
        echo -e "${YELLOW}No targets to scan. Exiting live host discovery.${RESET}"
        log_message "WARNING" "No targets to scan for live host discovery."
        return
    fi

    for TARGET in "${TARGETS[@]}"; do
        sem "$MAX_LIVE_HOST_PROCESSES"
        (
            echo -e "${BLUE}Scanning target: $TARGET${RESET}"
            log_message "INFO" "Scanning target: $TARGET"

            # Sanitize target for filenames
            SANITIZED_TARGET=$(echo "$TARGET" | tr '/.' '_')

            # Run multiple ping scans in parallel for each target, saving .gnmap files
            nmap -vv -n -sn -PE -oA "$ROOT_DIR/Live_Host/live_hosts_icmp_echo_${SANITIZED_TARGET}" "$TARGET"
            nmap -vv -n -sn -PO -oA "$ROOT_DIR/Live_Host/live_hosts_icmp_proto_ping_${SANITIZED_TARGET}" "$TARGET"
            nmap -vv -n -sn -PP -oA "$ROOT_DIR/Live_Host/live_hosts_timestamp_ping_${SANITIZED_TARGET}" "$TARGET"
            nmap -vv -n -sn -PY132,2905 -oA "$ROOT_DIR/Live_Host/live_hosts_sctp_ping_${SANITIZED_TARGET}" "$TARGET"
            nmap -vv -n -Pn -sS --reason --open -T4 \
                -p20,21,22,23,25,53,67,68,69,80,88,110,119,123,135,137,138,139,143,161,162,179,194,263,389,443,445,465,500,514,541,587,902,993,995,1433,1434,1521,1700,1701,1723,1900,1935,2077,2078,2082,2083,2086,2087,2089,2091,2095,2096,3268,3306,3389,3478,3479,4353,4444,5000,5060,5061,5353,11211 \
                -oA "$ROOT_DIR/Live_Host/tcp_live_hosts_${SANITIZED_TARGET}" "$TARGET"
            nmap -vv -n -Pn -sU --reason --open -T4 --defeat-icmp-ratelimit \
                -p53,67,68,69,123,137,138,161,162,500,514,520,546,547,1194,1701,1723,1900,3478,3479,4500,5060,5061,5353,11211 \
                -oA "$ROOT_DIR/Live_Host/udp_live_hosts_1000_${SANITIZED_TARGET}" "$TARGET"
        ) &
    done
    wait

    echo -e "${GREEN}Live host discovery scans completed.${RESET}"
    log_message "INFO" "Live host discovery scans completed."

    # Extract live hosts from the .gnmap files
    echo -e "${GREEN}Extracting live hosts...${RESET}"
    log_message "INFO" "Extracting live hosts..."

    LIVE_HOSTS_FILE="$ROOT_DIR/live_hosts.txt"
    > "$LIVE_HOSTS_FILE"

    # Parse all .gnmap files to extract IPs with status Up
    grep -h "Status: Up" "$ROOT_DIR/Live_Host/"*.gnmap 2>/dev/null | awk '{print $2}' | sort -V | uniq >> "$LIVE_HOSTS_FILE"

    echo -e "${GREEN}Live hosts saved to $ROOT_DIR/live_hosts.txt${RESET}"
    log_message "INFO" "Live hosts saved to $ROOT_DIR/live_hosts.txt"
}

# --------------------------
# Function to run port scans
# --------------------------
run_port_scans() {
    echo -e "${GREEN}Starting port scans...${RESET}"
    log_message "INFO" "Starting port scans..."

    # Determine IPs to scan
    if [ "$USE_EXISTING" = true ] && [ -f "$ROOT_DIR/live_hosts.txt" ] && [ -s "$ROOT_DIR/live_hosts.txt" ]; then
        mapfile -t IPs < "$ROOT_DIR/live_hosts.txt"
    elif [ ${#TARGETS[@]} -gt 0 ] || [ -n "$TARGET_FILE" ]; then
        load_targets
        mapfile -t IPs < <(printf "%s\n" "${TARGETS[@]}")
    else
        if [ "$RUN_LIVE_HOST" = false ]; then
            echo -e "${RED}Error: No live_hosts.txt found. Use -l to perform live host discovery or provide targets via -t or -f.${RESET}" >&2
            log_message "ERROR" "No live_hosts.txt found and no targets specified."
            exit 1
        else
            echo -e "${RED}Error: No live hosts found and no targets specified. Use -t or -f to provide targets.${RESET}" >&2
            log_message "ERROR" "No live hosts found and no targets specified."
            exit 1
        fi
    fi

    # Exclude specified hosts
    if [ ${#EXCLUDE_HOSTS[@]} -gt 0 ]; then
        for ex_host in "${EXCLUDE_HOSTS[@]}"; do
            # Remove excluded host from IPs array
            IPs=("${IPs[@]/$ex_host}")
        done
    fi

    # Remove empty entries
    IPs=("${IPs[@]/#/}")
    IPs=("${IPs[@]/%/}")

    if [ ${#IPs[@]} -eq 0 ]; then
        echo -e "${YELLOW}No IPs to scan. Exiting port scan.${RESET}"
        log_message "WARNING" "No IPs to scan for port scan."
        return
    fi

    # Set the port scan options based on --top
    if [ "$SCAN_TOP_PORTS" = true ]; then
        TCP_PORT_OPTION="--top-ports 1000"
        TCP_OUTPUT_PREFIX="tcp_ports_top1000"
    else
        TCP_PORT_OPTION="-p-"
        TCP_OUTPUT_PREFIX="tcp_ports_full"
    fi

    # Handle excluded ports
    if [ -n "$EXCLUDE_PORTS" ]; then
        TCP_PORT_OPTION+=" --exclude-ports $EXCLUDE_PORTS"
    fi

    # Apply rate limiting options if set
    RATE_OPTIONS=""
    if [ -n "$MIN_RATE" ]; then
        RATE_OPTIONS+="--min-rate $MIN_RATE "
    fi
    if [ -n "$MAX_RATE" ]; then
        RATE_OPTIONS+="--max-rate $MAX_RATE "
    fi

    # Include additional Nmap arguments if provided
    NMAP_ARGS="$NMAP_ADDITIONAL_ARGS"

    # Run TCP scans with concurrency control
    echo -e "${GREEN}Starting TCP scans...${RESET}"
    log_message "INFO" "Starting TCP scans..."
    for ip in "${IPs[@]}"; do
        sem "$MAX_PORT_PROCESSES"
        (
            echo -e "${BLUE}Scanning TCP ports on $ip${RESET}"
            log_message "INFO" "Scanning TCP ports on $ip"

            SANITIZED_IP=$(echo "$ip" | tr '/.' '_')

            nmap -sS -n -Pn -vv $TCP_PORT_OPTION $RATE_OPTIONS $NMAP_ARGS --reason --open -T4 \
                -oA "$ROOT_DIR/Ports/tcp/${TCP_OUTPUT_PREFIX}_${SANITIZED_IP}" "$ip"
        ) &
    done
    wait

    # Run UDP scans with concurrency control
    echo -e "${GREEN}Starting UDP scans...${RESET}"
    log_message "INFO" "Starting UDP scans..."
    for ip in "${IPs[@]}"; do
        sem "$MAX_PORT_PROCESSES"
        (
            echo -e "${BLUE}Scanning UDP ports on $ip${RESET}"
            log_message "INFO" "Scanning UDP ports on $ip"

            SANITIZED_IP=$(echo "$ip" | tr '/.' '_')

            nmap -sU -n -Pn -vv --top-ports 1000 $RATE_OPTIONS $NMAP_ARGS --reason --open --defeat-icmp-ratelimit -T4 \
                -oA "$ROOT_DIR/Ports/udp/udp_ports_1000_${SANITIZED_IP}" "$ip"
        ) &
    done
    wait

    echo -e "${GREEN}Port scans completed.${RESET}"
    log_message "INFO" "Port scans completed."
}

# --------------------------
# Function to process .gnmap files for service scans
# --------------------------
process_gnmap_file() {
    local gnmap_file="$1"
    local protocol="$2"  # 'tcp' or 'udp'
    local services_dir="$ROOT_DIR/Services/$protocol"

    # Extract IP from the .gnmap file
    ip=$(awk '/^Host: /{print $2; exit}' "$gnmap_file")

    # Extract open ports from the .gnmap file
    ports=$(grep -E "Ports: " "$gnmap_file" | awk -F'Ports: ' '{print $2}' | tr ',' '\n' | awk -v proto="$protocol" '/open\/'"$protocol"'/{print $1}' | cut -d '/' -f1 | sort -n | uniq | paste -sd, -)

    # Apply exclusion if EXCLUDE_PORTS is set
    if [ -n "$EXCLUDE_PORTS" ]; then
        ports=$(echo "$ports" | tr ',' '\n' | grep -v -w -E "$(echo "$EXCLUDE_PORTS" | sed 's/,/|/g')" | paste -sd, -)
    fi

    if [ -n "$ports" ]; then
        echo -e "${BLUE}Scanning $protocol services on $ip with ports $ports${RESET}"
        log_message "INFO" "Scanning $protocol services on $ip with ports $ports"

        SANITIZED_IP=$(echo "$ip" | tr '/.' '_')

        if [ "$protocol" == "tcp" ]; then
            nmap_cmd=(nmap -sV -vv -n -Pn -T4 -p"$ports" $NMAP_ADDITIONAL_ARGS --reason --open -oA "$services_dir/${protocol}_services_${SANITIZED_IP}" "$ip")
        else
            nmap_cmd=(nmap -sV -sU -vv -n -Pn -T4 -p"$ports" $NMAP_ADDITIONAL_ARGS --reason --open -oA "$services_dir/${protocol}_services_${SANITIZED_IP}" "$ip")
        fi

        echo -e "${GREEN}Running: ${nmap_cmd[*]}${RESET}"
        log_message "INFO" "Running: ${nmap_cmd[*]}"
        "${nmap_cmd[@]}"
    else
        echo -e "${YELLOW}No open $protocol ports found for $ip in $gnmap_file${RESET}"
        log_message "WARNING" "No open $protocol ports found for $ip in $gnmap_file"
    fi
}


# --------------------------
# Function to run service scans
# --------------------------
run_service_scans() {
    echo -e "${GREEN}Starting detailed service scans...${RESET}"
    log_message "INFO" "Starting detailed service scans..."

    # Determine if port scan results exist
    tcp_gnmap_files=("$ROOT_DIR/Ports/tcp/"*.gnmap)
    udp_gnmap_files=("$ROOT_DIR/Ports/udp/"*.gnmap)

    # Initialize a flag to check if port scans need to be run
    need_port_scan=false

    if [ "$USE_EXISTING" = false ]; then
        if [ ${#tcp_gnmap_files[@]} -eq 0 ] && [ ${#udp_gnmap_files[@]} -eq 0 ]; then
            if [ ${#TARGETS[@]} -gt 0 ] || [ -n "$TARGET_FILE" ]; then
                need_port_scan=true
            else
                echo -e "${RED}Error: No port scan results found and no targets specified. Use -p to perform port scans or -e to use existing live_hosts.txt.${RESET}" >&2
                log_message "ERROR" "No port scan results found and no targets specified."
                exit 1
            fi
        fi
    fi

    # Perform port scans if necessary
    if [ "$need_port_scan" = true ]; then
        echo -e "${YELLOW}No port scan results found. Performing port scans on specified targets...${RESET}"
        log_message "WARNING" "No port scan results found. Performing port scans on specified targets..."
        RUN_PORT_SCAN=true
        run_port_scans
    fi

    # Update the list of .gnmap files in case port scans were just performed
    tcp_gnmap_files=("$ROOT_DIR/Ports/tcp/"*.gnmap)
    udp_gnmap_files=("$ROOT_DIR/Ports/udp/"*.gnmap)

    # Process TCP .gnmap files
    if [ ${#tcp_gnmap_files[@]} -gt 0 ]; then
        echo -e "${GREEN}Processing TCP .gnmap files...${RESET}"
        log_message "INFO" "Processing TCP .gnmap files..."
        for gnmap_file in "${tcp_gnmap_files[@]}"; do
            [ -e "$gnmap_file" ] || continue
            sem "$MAX_SERVICE_PROCESSES"
            (
                process_gnmap_file "$gnmap_file" "tcp"
            ) &
        done
        wait
    else
        echo -e "${YELLOW}No TCP .gnmap files found to process.${RESET}"
        log_message "WARNING" "No TCP .gnmap files found to process."
    fi

    # Process UDP .gnmap files
    if [ ${#udp_gnmap_files[@]} -gt 0 ]; then
        echo -e "${GREEN}Processing UDP .gnmap files...${RESET}"
        log_message "INFO" "Processing UDP .gnmap files..."
        for gnmap_file in "${udp_gnmap_files[@]}"; do
            [ -e "$gnmap_file" ] || continue
            sem "$MAX_SERVICE_PROCESSES"
            (
                process_gnmap_file "$gnmap_file" "udp"
            ) &
        done
        wait
    else
        echo -e "${YELLOW}No UDP .gnmap files found to process.${RESET}"
        log_message "WARNING" "No UDP .gnmap files found to process."
    fi

    echo -e "${GREEN}Detailed service scans completed.${RESET}"
    log_message "INFO" "Detailed service scans completed."
}

# --------------------------
# Helper Functions for Reports
# --------------------------

# Function to extract live hosts
extract_live_hosts() {
    if [ -f "$ROOT_DIR/live_hosts.txt" ] && [ -s "$ROOT_DIR/live_hosts.txt" ]; then
        sort -u "$ROOT_DIR/live_hosts.txt"
    else
        # Derive live hosts from port scans (TCP and UDP)
        grep -E "^Host: " "$ROOT_DIR/Ports/tcp/"*.gnmap "$ROOT_DIR/Ports/udp/"*.gnmap 2>/dev/null | awk '{print $2}' | sort -u | grep -v '^$'
    fi
}

# Function to extract unique open ports
extract_unique_ports() {
    local protocol="$1"
    if ls "$ROOT_DIR/Ports/$protocol/"*.gnmap 1> /dev/null 2>&1; then
        grep -h "Ports:" "$ROOT_DIR/Ports/$protocol/"*.gnmap 2>/dev/null | \
            grep -E "open/$protocol" | \
            awk -F'Ports: ' '{print $2}' | \
            tr ',' '\n' | \
            awk -v proto="$protocol" '/open\/'"$protocol"'/{print $1}' | \
            cut -d '/' -f1 | \
            sort -n | \
            uniq
    else
        echo ""
    fi
}

# --------------------------
# Function to generate color-coded text report
# --------------------------
generate_report_txt() {
    echo -e "${GREEN}Generating text report...${RESET}"
    log_message "INFO" "Generating text report..."

    REPORT_FILE="$ROOT_DIR/report.txt"
    > "$REPORT_FILE"

    # Helper function to add colors
    color_echo() {
        echo -e "${!1}$2${RESET}" >> "$REPORT_FILE"
    }

    # Header with color
    echo -e "${GREEN}==========================${RESET}" >> "$REPORT_FILE"
    echo -e "${GREEN}       Nmap Scan Report    ${RESET}" >> "$REPORT_FILE"
    echo -e "${GREEN}==========================${RESET}" >> "$REPORT_FILE"
    echo "" >> "$REPORT_FILE"

    # Add a timestamp to the report
    color_echo "CYAN" "Scan Date: $(date)"
    echo "" >> "$REPORT_FILE"

    # Section 1: Summary
    color_echo "MAGENTA" "== Summary =="
    # Total Live Hosts
    total_live_hosts=$(extract_live_hosts | wc -l)

    # Unique Open TCP Ports
    unique_tcp_ports=$(extract_unique_ports "tcp" | wc -l)

    # Unique Open UDP Ports
    unique_udp_ports=$(extract_unique_ports "udp" | wc -l)

    color_echo "YELLOW" "Total Live Hosts: $total_live_hosts"
    color_echo "YELLOW" "Unique Open TCP Ports: $unique_tcp_ports"
    color_echo "YELLOW" "Unique Open UDP Ports: $unique_udp_ports"
    echo "" >> "$REPORT_FILE"

    # Section 2: Live Hosts
    color_echo "MAGENTA" "== Live Hosts =="
    extract_live_hosts | while read -r host; do
        color_echo "GREEN" "$host"
    done
    echo "" >> "$REPORT_FILE"

    # Section 3: Hosts and Open TCP Ports
    color_echo "MAGENTA" "== Hosts and Open TCP Ports =="
    if ls "$ROOT_DIR/Ports/tcp/"*.gnmap 1> /dev/null 2>&1; then
        for gnmap_file in "$ROOT_DIR/Ports/tcp/"*.gnmap; do
            [ -e "$gnmap_file" ] || continue
            ip=$(awk '/^Host: /{print $2; exit}' "$gnmap_file")
            if [ -n "$ip" ]; then
                color_echo "BLUE" "Host: $ip"
                open_ports=$(grep "Ports:" "$gnmap_file" | \
                    awk -F'Ports: ' '{print $2}' | \
                    tr ',' '\n' | \
                    awk '/open\/tcp/{print $1}' | \
                    cut -d '/' -f1 | \
                    sort -n | \
                    paste -sd, -)
                if [ -n "$open_ports" ]; then
                    color_echo "YELLOW" "  Open TCP Ports: $open_ports"
                else
                    color_echo "RED" "  Open TCP Ports: None"
                fi
                echo "" >> "$REPORT_FILE"
            fi
        done
    else
        color_echo "RED" "No TCP port scan results available."
    fi

    # Section 4: Hosts and Open UDP Ports
    color_echo "MAGENTA" "== Hosts and Open UDP Ports =="
    if ls "$ROOT_DIR/Ports/udp/"*.gnmap 1> /dev/null 2>&1; then
        for gnmap_file in "$ROOT_DIR/Ports/udp/"*.gnmap; do
            [ -e "$gnmap_file" ] || continue
            ip=$(awk '/^Host: /{print $2; exit}' "$gnmap_file")
            if [ -n "$ip" ]; then
                color_echo "BLUE" "Host: $ip"
                open_ports=$(grep "Ports:" "$gnmap_file" | \
                    awk -F'Ports: ' '{print $2}' | \
                    tr ',' '\n' | \
                    awk '/open\/udp/{print $1}' | \
                    cut -d '/' -f1 | \
                    sort -n | \
                    paste -sd, -)
                if [ -n "$open_ports" ]; then
                    color_echo "YELLOW" "  Open UDP Ports: $open_ports"
                else
                    color_echo "RED" "  Open UDP Ports: None"
                fi
                echo "" >> "$REPORT_FILE"
            fi
        done
    else
        color_echo "RED" "No UDP port scan results available."
    fi

    # Section 5: Hosts, Open TCP Ports, and Services
    color_echo "MAGENTA" "== Hosts, Open TCP Ports, and Services =="
    if ls "$ROOT_DIR/Services/tcp/"*.gnmap 1> /dev/null 2>&1; then
        for service_file in "$ROOT_DIR/Services/tcp/"*.gnmap; do
            [ -e "$service_file" ] || continue
            ip=$(awk '/^Host: /{print $2; exit}' "$service_file")
            if [ -n "$ip" ]; then
                color_echo "BLUE" "Host: $ip"
                color_echo "YELLOW" "  TCP Services:"
                # Extract port and service
                grep "Ports:" "$service_file" | \
                    awk -F'Ports: ' '{print $2}' | \
                    tr ',' '\n' | \
                    awk -F '/' '/open\/tcp/ {
                        service = $(NF-1)
                        print "    Port: " $1 " - " service
                    }' | \
                    sort -n >> "$REPORT_FILE"
                echo "" >> "$REPORT_FILE"
            fi
        done
    else
        color_echo "RED" "No TCP service scan results available."
    fi

    # Section 6: Hosts, Open UDP Ports, and Services
    color_echo "MAGENTA" "== Hosts, Open UDP Ports, and Services =="
    if ls "$ROOT_DIR/Services/udp/"*.gnmap 1> /dev/null 2>&1; then
        for service_file in "$ROOT_DIR/Services/udp/"*.gnmap; do
            [ -e "$service_file" ] || continue
            ip=$(awk '/^Host: /{print $2; exit}' "$service_file")
            if [ -n "$ip" ]; then
                color_echo "BLUE" "Host: $ip"
                color_echo "YELLOW" "  UDP Services:"
                # Extract port and service
                grep "Ports:" "$service_file" | \
                    awk -F'Ports: ' '{print $2}' | \
                    tr ',' '\n' | \
                    awk -F '/' '/open\/udp/ {
                        service = $(NF-1)
                        print "    Port: " $1 " - " service
                    }' | \
                    sort -n >> "$REPORT_FILE"
                echo "" >> "$REPORT_FILE"
            fi
        done
    else
        color_echo "RED" "No UDP service scan results available."
    fi

    # Section 7: Unique Live Hosts
    color_echo "MAGENTA" "== Unique Live Hosts =="
    extract_live_hosts | while read -r host; do
        color_echo "GREEN" "$host"
    done
    echo "" >> "$REPORT_FILE"

    # Section 8: Unique Open TCP Ports
    color_echo "MAGENTA" "== Unique Open TCP Ports =="
    unique_tcp_ports_list=$(extract_unique_ports "tcp")
    if [ -n "$unique_tcp_ports_list" ]; then
        echo "$unique_tcp_ports_list" | while read -r port; do
            color_echo "YELLOW" "$port"
        done
    else
        color_echo "RED" "No TCP ports found."
    fi
    echo "" >> "$REPORT_FILE"

    # Section 9: Unique Open UDP Ports
    color_echo "MAGENTA" "== Unique Open UDP Ports =="
    unique_udp_ports_list=$(extract_unique_ports "udp")
    if [ -n "$unique_udp_ports_list" ]; then
        echo "$unique_udp_ports_list" | while read -r port; do
            color_echo "YELLOW" "$port"
        done
    else
        color_echo "RED" "No UDP ports found."
    fi
    echo "" >> "$REPORT_FILE"

    echo -e "${GREEN}Report generated at $REPORT_FILE${RESET}"
    log_message "INFO" "Report generated at $REPORT_FILE"
}

# --------------------------
# Function to generate HTML report
# --------------------------
generate_report_html() {
    echo -e "${GREEN}Generating HTML report...${RESET}"
    log_message "INFO" "Generating HTML report..."

    HTML_REPORT_FILE="$ROOT_DIR/report.html"
    > "$HTML_REPORT_FILE"

    # Start HTML
    cat <<EOF >> "$HTML_REPORT_FILE"
<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset='UTF-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <title>Nmap Scan Report</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; background-color: #f0f8ff; }
        h1 { color: #2E8B57; }
        h2 { color: #4682B4; }
        h3 { color: #6A5ACD; }
        .summary { background-color: #F0F8FF; padding: 10px; border-radius: 5px; }
        .host { margin-bottom: 15px; padding: 10px; background-color: #ffffff; border-radius: 5px; box-shadow: 0 0 5px rgba(0,0,0,0.1); }
        .service { margin-left: 20px; }
        ul { list-style-type: none; padding-left: 0; }
        li { margin-bottom: 5px; }
        .green { color: #228B22; }
        .yellow { color: #DAA520; }
        .red { color: #B22222; }
        .blue { color: #1E90FF; }
    </style>
</head>
<body>
    <h1>Nmap Scan Report</h1>
    <p><strong>Scan Date:</strong> $(date)</p>
EOF

    # Section 1: Summary
    echo "<h2>Summary</h2>" >> "$HTML_REPORT_FILE"
    echo "<div class='summary'>" >> "$HTML_REPORT_FILE"
    # Total Live Hosts
    total_live_hosts=$(extract_live_hosts | wc -l)

    # Unique Open TCP Ports
    unique_tcp_ports=$(extract_unique_ports "tcp" | wc -l)

    # Unique Open UDP Ports
    unique_udp_ports=$(extract_unique_ports "udp" | wc -l)

    echo "<p><strong>Total Live Hosts:</strong> <span class='yellow'>$total_live_hosts</span></p>" >> "$HTML_REPORT_FILE"
    echo "<p><strong>Unique Open TCP Ports:</strong> <span class='yellow'>$unique_tcp_ports</span></p>" >> "$HTML_REPORT_FILE"
    echo "<p><strong>Unique Open UDP Ports:</strong> <span class='yellow'>$unique_udp_ports</span></p>" >> "$HTML_REPORT_FILE"
    echo "</div>" >> "$HTML_REPORT_FILE"
    echo "" >> "$HTML_REPORT_FILE"

    # Section 2: Live Hosts
    echo "<h2>Live Hosts</h2>" >> "$HTML_REPORT_FILE"
    echo "<ul>" >> "$HTML_REPORT_FILE"
    extract_live_hosts | while read -r host; do
        echo "<li class='green'>$host</li>" >> "$HTML_REPORT_FILE"
    done
    echo "</ul>" >> "$HTML_REPORT_FILE"
    echo "" >> "$HTML_REPORT_FILE"

    # Section 3: Hosts and Open TCP Ports
    echo "<h2>Hosts and Open TCP Ports</h2>" >> "$HTML_REPORT_FILE"
    if ls "$ROOT_DIR/Ports/tcp/"*.gnmap 1> /dev/null 2>&1; then
        for gnmap_file in "$ROOT_DIR/Ports/tcp/"*.gnmap; do
            [ -e "$gnmap_file" ] || continue
            ip=$(awk '/^Host: /{print $2; exit}' "$gnmap_file")  # Modified line
            if [ -n "$ip" ]; then
                echo "<div class='host'>" >> "$HTML_REPORT_FILE"
                echo "<h3>Host: <span class='blue'>$ip</span></h3>" >> "$HTML_REPORT_FILE"
                open_ports=$(grep "Ports:" "$gnmap_file" | \
                    awk -F'Ports: ' '{print $2}' | \
                    tr ',' '\n' | \
                    awk '/open\/tcp/{print $1}' | \
                    cut -d '/' -f1 | \
                    sort -n | \
                    paste -sd, -)
                if [ -n "$open_ports" ]; then
                    echo "<p><strong>Open TCP Ports:</strong> <span class='yellow'>$open_ports</span></p>" >> "$HTML_REPORT_FILE"
                else
                    echo "<p><strong>Open TCP Ports:</strong> <span class='red'>None</span></p>" >> "$HTML_REPORT_FILE"
                fi
                echo "</div>" >> "$HTML_REPORT_FILE"
                echo "" >> "$HTML_REPORT_FILE"
            fi
        done
    else
        echo "<p class='red'>No TCP port scan results available.</p>" >> "$HTML_REPORT_FILE"
    fi

    # Section 4: Hosts and Open UDP Ports
    echo "<h2>Hosts and Open UDP Ports</h2>" >> "$HTML_REPORT_FILE"
    if ls "$ROOT_DIR/Ports/udp/"*.gnmap 1> /dev/null 2>&1; then
        for gnmap_file in "$ROOT_DIR/Ports/udp/"*.gnmap; do
            [ -e "$gnmap_file" ] || continue
            ip=$(awk '/^Host: /{print $2; exit}' "$gnmap_file")  # Modified line
            if [ -n "$ip" ]; then
                echo "<div class='host'>" >> "$HTML_REPORT_FILE"
                echo "<h3>Host: <span class='blue'>$ip</span></h3>" >> "$HTML_REPORT_FILE"
                open_ports=$(grep "Ports:" "$gnmap_file" | \
                    awk -F'Ports: ' '{print $2}' | \
                    tr ',' '\n' | \
                    awk '/open\/udp/{print $1}' | \
                    cut -d '/' -f1 | \
                    sort -n | \
                    paste -sd, -)
                if [ -n "$open_ports" ]; then
                    echo "<p><strong>Open UDP Ports:</strong> <span class='yellow'>$open_ports</span></p>" >> "$HTML_REPORT_FILE"
                else
                    echo "<p><strong>Open UDP Ports:</strong> <span class='red'>None</span></p>" >> "$HTML_REPORT_FILE"
                fi
                echo "</div>" >> "$HTML_REPORT_FILE"
                echo "" >> "$HTML_REPORT_FILE"
            fi
        done
    else
        echo "<p class='red'>No UDP port scan results available.</p>" >> "$HTML_REPORT_FILE"
    fi

    # Section 5: Hosts, Open TCP Ports, and Services
    echo "<h2>Hosts, Open TCP Ports, and Services</h2>" >> "$HTML_REPORT_FILE"
    if ls "$ROOT_DIR/Services/tcp/"*.gnmap 1> /dev/null 2>&1; then
        for service_file in "$ROOT_DIR/Services/tcp/"*.gnmap; do
            [ -e "$service_file" ] || continue
            ip=$(awk '/^Host: /{print $2; exit}' "$service_file")
            if [ -n "$ip" ]; then
                echo "<div class='host'>" >> "$HTML_REPORT_FILE"
                echo "<h3>Host: <span class='blue'>$ip</span></h3>" >> "$HTML_REPORT_FILE"
                echo "<p><strong>TCP Services:</strong></p>" >> "$HTML_REPORT_FILE"
                echo "<ul class='service'>" >> "$HTML_REPORT_FILE"
                # Extract port and service
                grep "Ports:" "$service_file" | \
                    awk -F'Ports: ' '{print $2}' | \
                    tr ',' '\n' | \
                    awk -F '/' '/open\/tcp/ {
                        service = $(NF-1)
                        print "<li>Port: " $1 " - " service "</li>"
                    }' | \
                    sort -n >> "$HTML_REPORT_FILE"
                echo "</ul>" >> "$HTML_REPORT_FILE"
                echo "</div>" >> "$HTML_REPORT_FILE"
                echo "" >> "$HTML_REPORT_FILE"
            fi
        done
    else
        echo "<p class='red'>No TCP service scan results available.</p>" >> "$HTML_REPORT_FILE"
    fi

    # Section 6: Hosts, Open UDP Ports, and Services
    echo "<h2>Hosts, Open UDP Ports, and Services</h2>" >> "$HTML_REPORT_FILE"
    if ls "$ROOT_DIR/Services/udp/"*.gnmap 1> /dev/null 2>&1; then
        for service_file in "$ROOT_DIR/Services/udp/"*.gnmap; do
            [ -e "$service_file" ] || continue
            ip=$(awk '/^Host: /{print $2; exit}' "$service_file")
            if [ -n "$ip" ]; then
                echo "<div class='host'>" >> "$HTML_REPORT_FILE"
                echo "<h3>Host: <span class='blue'>$ip</span></h3>" >> "$HTML_REPORT_FILE"
                echo "<p><strong>UDP Services:</strong></p>" >> "$HTML_REPORT_FILE"
                echo "<ul class='service'>" >> "$HTML_REPORT_FILE"
                # Extract port and service
                grep "Ports:" "$service_file" | \
                    awk -F'Ports: ' '{print $2}' | \
                    tr ',' '\n' | \
                    awk -F '/' '/open\/udp/ {
                        service = $(NF-1)
                        print "<li>Port: " $1 " - " service "</li>"
                    }' | \
                    sort -n >> "$HTML_REPORT_FILE"
                echo "</ul>" >> "$HTML_REPORT_FILE"
                echo "</div>" >> "$HTML_REPORT_FILE"
                echo "" >> "$HTML_REPORT_FILE"
            fi
        done
    else
        echo "<p class='red'>No UDP service scan results available.</p>" >> "$HTML_REPORT_FILE"
    fi

    # Section 7: Unique Live Hosts
    echo "<h2>Unique Live Hosts</h2>" >> "$HTML_REPORT_FILE"
    echo "<ul>" >> "$HTML_REPORT_FILE"
    extract_live_hosts | while read -r host; do
        echo "<li class='green'>$host</li>" >> "$HTML_REPORT_FILE"
    done
    echo "</ul>" >> "$HTML_REPORT_FILE"
    echo "" >> "$HTML_REPORT_FILE"

    # Section 8: Unique Open TCP Ports
    echo "<h2>Unique Open TCP Ports</h2>" >> "$HTML_REPORT_FILE"
    echo "<ul>" >> "$HTML_REPORT_FILE"
    unique_tcp_ports_list=$(extract_unique_ports "tcp")
    if [ -n "$unique_tcp_ports_list" ]; then
        echo "$unique_tcp_ports_list" | while read -r port; do
            echo "<li class='yellow'>$port</li>" >> "$HTML_REPORT_FILE"
        done
    else
        echo "<li class='red'>No TCP ports found.</li>" >> "$HTML_REPORT_FILE"
    fi
    echo "</ul>" >> "$HTML_REPORT_FILE"
    echo "" >> "$HTML_REPORT_FILE"

    # Section 9: Unique Open UDP Ports
    echo "<h2>Unique Open UDP Ports</h2>" >> "$HTML_REPORT_FILE"
    echo "<ul>" >> "$HTML_REPORT_FILE"
    unique_udp_ports_list=$(extract_unique_ports "udp")
    if [ -n "$unique_udp_ports_list" ]; then
        echo "$unique_udp_ports_list" | while read -r port; do
            echo "<li class='yellow'>$port</li>" >> "$HTML_REPORT_FILE"
        done
    else
        echo "<li class='red'>No UDP ports found.</li>" >> "$HTML_REPORT_FILE"
    fi
    echo "</ul>" >> "$HTML_REPORT_FILE"
    echo "" >> "$HTML_REPORT_FILE"

    echo "</body>" >> "$HTML_REPORT_FILE"
    echo "</html>" >> "$HTML_REPORT_FILE"

    echo -e "${GREEN}HTML Report generated at $HTML_REPORT_FILE${RESET}"
    log_message "INFO" "HTML Report generated at $HTML_REPORT_FILE"
}

# --------------------------
# Function to cleanup scan results
# --------------------------
cleanup() {
    read -p "Are you sure you want to remove all scan results? [y/N]: " response
    case "$response" in
        [yY][eE][sS]|[yY])
            rm -rf "$ROOT_DIR"
            echo -e "${GREEN}All scan results have been removed.${RESET}"
            log_message "INFO" "All scan results have been removed."
            exit 0
            ;;
        *)
            echo -e "${YELLOW}Cleanup aborted.${RESET}"
            log_message "INFO" "Cleanup aborted."
            exit 0
            ;;
    esac
}

# --------------------------
# Function to parse command line arguments
# --------------------------
parse_arguments() {
    while [[ $# -gt 0 ]]; do
        key="$1"
        case $key in
            -l|--live-host)
                RUN_LIVE_HOST=true
                shift
                ;;
            -p|--port-scan)
                RUN_PORT_SCAN=true
                shift
                ;;
            -s|--service-scan)
                RUN_SERVICE_SCAN=true
                shift
                ;;
            -r|--report)
                RUN_REPORT=true
                shift
                ;;
            -H|--html-report)
                RUN_HTML_REPORT=true
                shift
                ;;
            -e|--existing)
                USE_EXISTING=true
                shift
                ;;
            -t|--target)
                if [[ -n "$2" && "$2" != -* ]]; then
                    validate_target "$2"
                    TARGETS+=("$2")
                    shift 2
                else
                    echo -e "${RED}Error: --target requires an argument.${RESET}" >&2
                    exit 1
                fi
                ;;
            -f|--target-file)
                if [[ -n "$2" && "$2" != -* ]]; then
                    TARGET_FILE="$2"
                    shift 2
                else
                    echo -e "${RED}Error: --target-file requires an argument.${RESET}" >&2
                    exit 1
                fi
                ;;
            --top)
                SCAN_TOP_PORTS=true
                shift
                ;;
            -x|--exclude)
                if [[ -n "$2" && "$2" != -* ]]; then
                    EXCLUDE_HOSTS+=("$2")
                    shift 2
                else
                    echo -e "${RED}Error: --exclude requires an argument.${RESET}" >&2
                    exit 1
                fi
                ;;
            -X|--exclude-ports)
                if [[ -n "$2" && "$2" != -* ]]; then
                    EXCLUDE_PORTS="$2"
                    shift 2
                else
                    echo -e "${RED}Error: --exclude-ports requires an argument.${RESET}" >&2
                    exit 1
                fi
                ;;
            --min-rate)
                if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then
                    MIN_RATE="$2"
                    shift 2
                else
                    echo -e "${RED}Error: --min-rate requires a numeric argument.${RESET}" >&2
                    exit 1
                fi
                ;;
            --max-rate)
                if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then
                    MAX_RATE="$2"
                    shift 2
                else
                    echo -e "${RED}Error: --max-rate requires a numeric argument.${RESET}" >&2
                    exit 1
                fi
                ;;
            -M|--max-port-processes)
                if [[ -n "$2" && "$2" =~ ^[1-9][0-9]*$ ]]; then
                    MAX_PORT_PROCESSES="$2"
                    shift 2
                else
                    echo -e "${RED}Error: --max-port-processes requires a positive integer.${RESET}" >&2
                    exit 1
                fi
                ;;
            -S|--max-service-processes)
                if [[ -n "$2" && "$2" =~ ^[1-9][0-9]*$ ]]; then
                    MAX_SERVICE_PROCESSES="$2"
                    shift 2
                else
                    echo -e "${RED}Error: --max-service-processes requires a positive integer.${RESET}" >&2
                    exit 1
                fi
                ;;
            --nmap-args)
                if [[ -n "$2" ]]; then
                    NMAP_ADDITIONAL_ARGS="$2"
                    shift 2
                else
                    echo -e "${RED}Error: --nmap-args requires an argument.${RESET}" >&2
                    exit 1
                fi
                ;;
            --verbosity)
                if [[ -n "$2" && "$2" =~ ^[0-2]$ ]]; then
                    VERBOSITY="$2"
                    shift 2
                else
                    echo -e "${RED}Error: --verbosity requires a value between 0 and 2.${RESET}" >&2
                    exit 1
                fi
                ;;
            -c|--cleanup)
                echo -e "${YELLOW}Cleaning up all scan results...${RESET}"
                cleanup
                ;;
            -h|--help)
                display_help
                ;;
            *)
                echo -e "${RED}Unknown option: $1${RESET}" >&2
                display_help
                ;;
        esac
    done

    # If no scan options are provided, but --nmap-args is provided, set RUN_CUSTOM_NMAP to true
    if [ "$RUN_LIVE_HOST" = false ] && [ "$RUN_PORT_SCAN" = false ] && [ "$RUN_SERVICE_SCAN" = false ] && [ -n "$NMAP_ADDITIONAL_ARGS" ]; then
        RUN_CUSTOM_NMAP=true
    fi
}

# --------------------------
# Main Execution Flow
# --------------------------

main() {
    # Check if the script is run as root
    check_root

    # Parse command line arguments
    parse_arguments "$@"

    # Prepare necessary directories
    prepare_directories

    # Initialize log file
    mkdir -p "$(dirname "$LOG_FILE")"
    > "$LOG_FILE"

    # Execute the selected scans
    if [ "$RUN_LIVE_HOST" = true ]; then
        run_live_host_scans
    fi

    if [ "$RUN_PORT_SCAN" = true ]; then
        run_port_scans
    fi

    if [ "$RUN_SERVICE_SCAN" = true ]; then
        run_service_scans
    fi

    if [ "$RUN_CUSTOM_NMAP" = true ]; then
        run_custom_nmap_scan
    fi

    # Generate reports if requested
    if [ "$RUN_REPORT" = true ] || [ "$RUN_HTML_REPORT" = true ]; then
        # Check if live_hosts.txt exists or derive from scan files
        if [ ! -f "$ROOT_DIR/live_hosts.txt" ] || [ ! -s "$ROOT_DIR/live_hosts.txt" ]; then
            echo -e "${YELLOW}live_hosts.txt not found or empty. Attempting to derive live hosts from existing port scans...${RESET}"
            log_message "WARNING" "live_hosts.txt not found. Deriving live hosts from port scans."
            extract_live_hosts > "$ROOT_DIR/live_hosts.txt"
            if [ -s "$ROOT_DIR/live_hosts.txt" ]; then
                echo -e "${GREEN}Derived live hosts saved to $ROOT_DIR/live_hosts.txt${RESET}"
                log_message "INFO" "Derived live hosts saved to $ROOT_DIR/live_hosts.txt"
            else
                echo -e "${RED}Error: No live hosts found from existing port scans. Cannot generate reports.${RESET}" >&2
                log_message "ERROR" "No live hosts found. Cannot generate reports."
                exit 1
            fi
        fi

        # Proceed to generate reports if the necessary files are present
        if [ -f "$ROOT_DIR/live_hosts.txt" ] && [ -s "$ROOT_DIR/live_hosts.txt" ]; then
            if [ "$RUN_REPORT" = true ]; then
                generate_report_txt
            fi
            if [ "$RUN_HTML_REPORT" = true ]; then
                generate_report_html
            fi
        else
            echo -e "${RED}Error: live_hosts.txt is missing or empty after attempting to derive live hosts.${RESET}" >&2
            log_message "ERROR" "live_hosts.txt is missing or empty."
            exit 1
        fi
    fi

    # If no actions are specified, display help
    if [ "$RUN_REPORT" = false ] && [ "$RUN_HTML_REPORT" = false ] && [ "$RUN_LIVE_HOST" = false ] && [ "$RUN_PORT_SCAN" = false ] && [ "$RUN_SERVICE_SCAN" = false ] && [ "$RUN_CUSTOM_NMAP" = false ]; then
        echo -e "${YELLOW}No actions specified. Use -h for help.${RESET}"
        exit 1
    fi

    echo -e "${GREEN}All selected operations completed.${RESET}"
    log_message "INFO" "All selected operations completed."
    exit 0
}

# --------------------------
# Execute the main function
# --------------------------
main "$@"
