#!/bin/bash

# MacOS DNSFilter/DNS Agent Diagnostics Script
# This script detects installed versions (Branded and/or White Label),
# collects diagnostic information, and packages it into a zip file
# in the user's Downloads folder.
# Compatible with older bash versions (e.g., macOS default).

# Check if script is running with sudo/root privileges
if [ "$EUID" -ne 0 ]; then
  echo "This script requires root privileges to access system directories."
  echo "Please run with sudo: sudo $0"
  exit 1
fi

# --- Define Product Configurations (using prefixed variables) ---

# Branded Product Details
DNSFilter_KEY_NAME="DNSFilter" # Used for array of installed keys
DNSFilter_APP_NAME_DISPLAY="DNSFilter Agent"
DNSFilter_APP_SUPPORT_PATH_NAME="DNSFilter Agent" # Dir name in /Library/Application Support
DNSFilter_BUNDLE_ID_BASE="com.dnsfilter.agent.macos"
DNSFilter_DATA_SUBDIR="DNSFilter_CollectedData" # Subdir in the zip for its files

# White Label Product Details
DNSAgent_KEY_NAME="DNSAgent"
DNSAgent_APP_NAME_DISPLAY="DNS Agent"
DNSAgent_APP_SUPPORT_PATH_NAME="DNS Agent"
DNSAgent_BUNDLE_ID_BASE="io.netalerts.agent.macos"
DNSAgent_DATA_SUBDIR="DNSAgent_CollectedData"

GROUP_CONTAINER_PREFIX="Y532KV8739" # This seems constant

# --- Detect Installed Versions ---
INSTALLED_PRODUCT_KEYS=() # Array to store keys of detected products (e.g., "DNSFilter", "DNSAgent")

echo "Detecting installed versions..."
# Check for Branded
branded_app_support_full_path="/Library/Application Support/${DNSFilter_APP_SUPPORT_PATH_NAME}"
if [ -d "${branded_app_support_full_path}" ]; then
    INSTALLED_PRODUCT_KEYS+=("DNSFilter") # Use the prefix as the key
    echo "Found: ${DNSFilter_APP_NAME_DISPLAY}"
fi

# Check for White Label
whitelabel_app_support_full_path="/Library/Application Support/${DNSAgent_APP_SUPPORT_PATH_NAME}"
if [ -d "${whitelabel_app_support_full_path}" ]; then
    INSTALLED_PRODUCT_KEYS+=("DNSAgent") # Use the prefix as the key
    echo "Found: ${DNSAgent_APP_NAME_DISPLAY}"
fi

if [ ${#INSTALLED_PRODUCT_KEYS[@]} -eq 0 ]; then
    echo "ERROR: No recognized DNSFilter or DNS Agent software found in /Library/Application Support."
    echo "Please ensure the software is installed correctly."
    exit 1
fi

# --- Setup Temp Dir, Log File, and Zip File Name ---
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
CURRENT_USER=$(who | awk '{print $1}' | head -1)
USER_HOME=$(dscl . -read "/Users/${CURRENT_USER}" NFSHomeDirectory | awk '{print $2}')
if [ -z "${USER_HOME}" ]; then
    USER_HOME=$(eval echo ~${CURRENT_USER})
fi

ZIP_FILE_PRODUCT_PREFIX=$(IFS=_ ; echo "${INSTALLED_PRODUCT_KEYS[*]}") # e.g., DNSFilter, DNSAgent, or DNSFilter_DNSAgent
TEMP_DIR_NAME_BASE="${ZIP_FILE_PRODUCT_PREFIX}Diagnostics"
TEMP_DIR="/tmp/${TEMP_DIR_NAME_BASE}_${TIMESTAMP}"
LOG_FILE="${TEMP_DIR}/diagnostics_report.txt"
ZIP_FILE="${USER_HOME}/Downloads/${TEMP_DIR_NAME_BASE}_${TIMESTAMP}.zip"

echo "======================================================"
echo "Diagnostics Tool for MacOS"
echo "Products found: ${ZIP_FILE_PRODUCT_PREFIX}"
echo "Collecting diagnostic information for troubleshooting..."
echo "======================================================"

mkdir -p "${TEMP_DIR}"
echo "Created temporary directory at ${TEMP_DIR}"

# --- Start Main Diagnostics Report ---
{
    echo "Diagnostics Report"
    echo "Products Detected: ${ZIP_FILE_PRODUCT_PREFIX}"
    echo "Generated on: $(date)"
    echo "======================================================"
} > "${LOG_FILE}"

# --- Collect System-Wide Information (Collected Once) ---
echo "Collecting system-wide information..."
{
    echo ""
    echo "SYSTEM INFORMATION"
    echo "======================================================"
    sw_vers
    echo ""
    uname -a
    echo ""

    echo "NETWORK INFORMATION"
    echo "======================================================"
    echo "Active Network Adapters:"
    echo "------------------------"
} >> "${LOG_FILE}"

PRIMARY_INTERFACE=$(route -n get default | awk '/interface:/{print $2}')
for interface in $(ifconfig -l); do
    ip=$(ifconfig $interface | awk '/inet /{print $2}')
    if [ -n "$ip" ]; then
        {
            echo "Adapter: $interface"
            router=$(netstat -nr | grep -E "^default|^0.0.0.0" | grep "$interface" | awk '{print $2}' | head -1)
            if [ -z "$router" ] && [ "$interface" == "$PRIMARY_INTERFACE" ]; then
                 router=$(netstat -nr | grep -E "^default|^0.0.0.0" | awk '{print $2}' | head -1)
            fi
            dns_servers=$(scutil --dns | grep nameserver | awk '{print $3}' | sort -u | tr '\n' ' ')
            echo "IP address: $ip"
            echo "Router: ${router:-N/A}"
            echo "System DNS Servers: ${dns_servers:-N/A}"
            echo ""
        } >> "${LOG_FILE}"
    fi
done

echo "Collecting WiFi information..."
{
    echo "WIFI STATUS"
    echo "======================================================"
} >> "${LOG_FILE}"
WIFI_INTERFACE=$(networksetup -listallhardwareports | awk '/Wi-Fi|AirPort/{getline; print $2}' | head -1)
if [ -n "$WIFI_INTERFACE" ]; then
    {
        echo "Wi-Fi Interface: $WIFI_INTERFACE"
        /usr/sbin/networksetup -getairportnetwork "$WIFI_INTERFACE"
        echo "---------------"
        /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I "$WIFI_INTERFACE"
        echo "---------------"
        /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -s "$WIFI_INTERFACE" # Scan might take a moment
    } >> "${LOG_FILE}" 2>&1
else
    echo "No Wi-Fi interface found or Wi-Fi is off." >> "${LOG_FILE}"
fi
echo "" >> "${LOG_FILE}"

echo "Performing network tests..."
{
    echo "NETWORK TESTS"
    echo "======================================================"
    echo "Ping to 8.8.8.8:"
    ping -c 4 8.8.8.8
    echo ""
    echo "DNS lookups:"
    echo "nslookup -type=txt debug.dnsfilter.com"
    nslookup -type=txt debug.dnsfilter.com
    echo ""
    echo "nslookup -type=txt debug.dnsfilter.com 103.247.36.36"
    nslookup -type=txt debug.dnsfilter.com 103.247.36.36
    echo ""
    echo "nslookup -type=txt debug.dnsfilter.com 103.247.37.37"
    nslookup -type=txt debug.dnsfilter.com 103.247.37.37
    echo ""
} >> "${LOG_FILE}" 2>&1

echo "Checking port 53 usage..."
{
    echo "PORT 53 USAGE"
    echo "======================================================"
    echo "The following PIDs and Applications are using port 53:"
    lsof -i :53 | awk '{print $2, $1}'
    echo ""
} >> "${LOG_FILE}" 2>&1
# --- End System-Wide Information ---


# --- Loop Through Each Detected Product for Specific Data Collection ---
for product_key_prefix in "${INSTALLED_PRODUCT_KEYS[@]}"; do # product_key_prefix will be "DNSFilter" or "DNSAgent"
    # Use indirect expansion to get product-specific variables
    app_name_display_var="${product_key_prefix}_APP_NAME_DISPLAY"
    APP_NAME_DISPLAY="${!app_name_display_var}"

    app_support_dir_name_var="${product_key_prefix}_APP_SUPPORT_PATH_NAME"
    APP_SUPPORT_DIR_NAME="${!app_support_dir_name_var}"

    bundle_id_base_var="${product_key_prefix}_BUNDLE_ID_BASE"
    BUNDLE_ID_BASE="${!bundle_id_base_var}"

    product_data_subdir_var="${product_key_prefix}_DATA_SUBDIR"
    PRODUCT_DATA_SUBDIR_NAME="${!product_data_subdir_var}"

    # Create a dedicated directory within TEMP_DIR for this product's files
    PRODUCT_SPECIFIC_TEMP_DIR="${TEMP_DIR}/${PRODUCT_DATA_SUBDIR_NAME}"
    mkdir -p "${PRODUCT_SPECIFIC_TEMP_DIR}"
    mkdir -p "${PRODUCT_SPECIFIC_TEMP_DIR}/ApplicationSupportFiles" # For daemon.conf, .info
    mkdir -p "${PRODUCT_SPECIFIC_TEMP_DIR}/GroupContainerLogs"
    mkdir -p "${PRODUCT_SPECIFIC_TEMP_DIR}/HelperLogs"


    echo "Collecting data for: ${APP_NAME_DISPLAY}..."
    # Append to the main log file, under a section for this product
    {
        echo ""
        echo "======================================================"
        echo "PRODUCT-SPECIFIC DATA FOR: ${APP_NAME_DISPLAY}"
        echo "(Files for this product are in the '${PRODUCT_DATA_SUBDIR_NAME}' folder in the zip)"
        echo "======================================================"
    } >> "${LOG_FILE}"

    # Derived paths for the current product
    FULL_APP_SUPPORT_PATH="/Library/Application Support/${APP_SUPPORT_DIR_NAME}"
    DAEMON_INFO_FILE="${FULL_APP_SUPPORT_PATH}/daemon.info"
    DAEMON_CONF_FILE="${FULL_APP_SUPPORT_PATH}/daemon.conf"
    CURRENT_GROUP_CONTAINER_ID="${GROUP_CONTAINER_PREFIX}.${BUNDLE_ID_BASE}"
    CURRENT_LOG_DIR_HELPER_NAME="${BUNDLE_ID_BASE}.helper"

    # Agent Status for this product
    {
        echo "${APP_NAME_DISPLAY} STATUS"
        echo "-------------------------------------"
    } >> "${LOG_FILE}"
    if [ -d "${FULL_APP_SUPPORT_PATH}" ]; then
        echo "${APP_NAME_DISPLAY} application support directory exists at ${FULL_APP_SUPPORT_PATH}" >> "${LOG_FILE}"
        if [ -f "${DAEMON_INFO_FILE}" ]; then
            echo "daemon.info contents:" >> "${LOG_FILE}"
            cat "${DAEMON_INFO_FILE}" >> "${LOG_FILE}"
            AgentAddress=$(grep -i 'Address=' "${DAEMON_INFO_FILE}")
            AgentAddress=${AgentAddress#*Address=}
            if [ -z "$AgentAddress" ]; then
                echo "${APP_NAME_DISPLAY} is not active (Address not found in daemon.info)" >> "${LOG_FILE}"
            else
                echo "${APP_NAME_DISPLAY} is active" >> "${LOG_FILE}"
                cat "${DAEMON_INFO_FILE}" | grep "Version" >> "${LOG_FILE}"
            fi
        else
            echo "${DAEMON_INFO_FILE} file not found" >> "${LOG_FILE}"
        fi
    else
        echo "${APP_NAME_DISPLAY} directory (${FULL_APP_SUPPORT_PATH}) not found during detailed check (should not happen if initial detection worked)" >> "${LOG_FILE}"
    fi
    echo "" >> "${LOG_FILE}"

    # Copying Logs and Configuration for this product
    echo "Copying logs and configuration for ${APP_NAME_DISPLAY} to ${PRODUCT_DATA_SUBDIR_NAME}..."
    {
        echo "COPIED FILES AND LOGS for ${APP_NAME_DISPLAY}"
        echo "-------------------------------------"
    } >> "${LOG_FILE}"

    # daemon.conf and daemon.info
    if [ -f "${DAEMON_CONF_FILE}" ]; then
        cp "${DAEMON_CONF_FILE}" "${PRODUCT_SPECIFIC_TEMP_DIR}/ApplicationSupportFiles/" 2>/dev/null
        echo "Copied: ${DAEMON_CONF_FILE} to ${PRODUCT_DATA_SUBDIR_NAME}/ApplicationSupportFiles/" >> "${LOG_FILE}"
    else
        echo "File not found: ${DAEMON_CONF_FILE}" >> "${LOG_FILE}"
    fi
    if [ -f "${DAEMON_INFO_FILE}" ]; then
        cp "${DAEMON_INFO_FILE}" "${PRODUCT_SPECIFIC_TEMP_DIR}/ApplicationSupportFiles/" 2>/dev/null
        echo "Copied: ${DAEMON_INFO_FILE} to ${PRODUCT_DATA_SUBDIR_NAME}/ApplicationSupportFiles/" >> "${LOG_FILE}"
    else
        echo "File not found: ${DAEMON_INFO_FILE}" >> "${LOG_FILE}"
    fi

    # Group Container logs
    SRC_GROUP_CONTAINER_DIR="/var/root/Library/Group Containers/${CURRENT_GROUP_CONTAINER_ID}/"
    DEST_GROUP_CONTAINER_SUBDIR="${PRODUCT_SPECIFIC_TEMP_DIR}/GroupContainerLogs/${CURRENT_GROUP_CONTAINER_ID}"
    if [ -d "${SRC_GROUP_CONTAINER_DIR}" ]; then
        mkdir -p "${DEST_GROUP_CONTAINER_SUBDIR}"
        cp -R "${SRC_GROUP_CONTAINER_DIR}"/* "${DEST_GROUP_CONTAINER_SUBDIR}/" 2>/dev/null
        echo "Copied contents of: ${SRC_GROUP_CONTAINER_DIR} to ${PRODUCT_DATA_SUBDIR_NAME}/GroupContainerLogs/${CURRENT_GROUP_CONTAINER_ID}/" >> "${LOG_FILE}"
    else
        echo "Directory not found: ${SRC_GROUP_CONTAINER_DIR}" >> "${LOG_FILE}"
    fi

    # Helper logs
    SRC_HELPER_LOG_DIR="/var/log/${CURRENT_LOG_DIR_HELPER_NAME}/"
    DEST_HELPER_LOG_SUBDIR="${PRODUCT_SPECIFIC_TEMP_DIR}/HelperLogs/${CURRENT_LOG_DIR_HELPER_NAME}"
    if [ -d "${SRC_HELPER_LOG_DIR}" ]; then
        mkdir -p "${DEST_HELPER_LOG_SUBDIR}"
        cp -R "${SRC_HELPER_LOG_DIR}"/* "${DEST_HELPER_LOG_SUBDIR}/" 2>/dev/null
        echo "Copied contents of: ${SRC_HELPER_LOG_DIR} to ${PRODUCT_DATA_SUBDIR_NAME}/HelperLogs/${CURRENT_LOG_DIR_HELPER_NAME}/" >> "${LOG_FILE}"
        # Specifically copy daemon.log if it exists in helper logs
        if [ -f "${SRC_HELPER_LOG_DIR}/daemon.log" ]; then
             cp "${SRC_HELPER_LOG_DIR}/daemon.log" "${DEST_HELPER_LOG_SUBDIR}/daemon.log.explicit_copy" 2>/dev/null # rename to avoid clash if dir already has it
             echo "Specifically copied: ${SRC_HELPER_LOG_DIR}/daemon.log" >> "${LOG_FILE}"
        fi
    else
        echo "Directory not found: ${SRC_HELPER_LOG_DIR}" >> "${LOG_FILE}"
    fi
    echo "" >> "${LOG_FILE}"
done
# --- End Product-Specific Data Collection Loop ---

# --- Create Zip File ---
echo "Creating zip file..."
cd "${TEMP_DIR}" || { echo "ERROR: Failed to change to temp directory ${TEMP_DIR}. Diagnostics aborted." >&2; exit 1; }
zip -ry "${ZIP_FILE}" . > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "ERROR: Failed to create zip file ${ZIP_FILE}" >&2
    echo "Contents of ${TEMP_DIR} that were to be zipped (please zip manually and send):"
    ls -lAR "${TEMP_DIR}"
    # Leaving TEMP_DIR for manual zipping if zip command fails
    exit 1
fi

# Set ownership of the zip file to the current user
chown "${CURRENT_USER}:staff" "${ZIP_FILE}"

# Cleanup temp directory
rm -rf "${TEMP_DIR}"

echo "======================================================"
echo "Diagnostics collection complete!"
echo "Zip file created at: ${ZIP_FILE}"
echo "======================================================"

exit 0