<?php
require_once 'Net/DNS2.php';
require_once '../../config.php';

// Set script to run in the background
ignore_user_abort(true);
set_time_limit(0);

// Check API key from headers
$headers = array_change_key_case(getallheaders(), CASE_LOWER); // Convert headers to lowercase
if (!isset($headers['api-key']) || $headers['api-key'] !== $apiKey_opt) {
    http_response_code(403);
    header('Location: ../../members/404.php');
    exit;
}

$mailer = new SendMail();

$log->system_debug('Starting blacklist monitoring script');

// Fetch active server paths from the database
$server_query = "SELECT server_path FROM evp_multi_server WHERE status = 'active'";
$server_result = $db->select($server_query);
if ($server_result->num_rows > 0) {
    while ($server = $server_result->fetch_assoc()) {
        // Remove protocol (http, https) and trailing slashes from server_path for rDNS
        $server_path = $server['server_path'];
        $server_path = preg_replace('#^https?://#', '', $server_path); // Remove http:// or https://
        $server_path = rtrim($server_path, '/'); // Remove trailing slash
        $log->system_debug('Checking server: ' . $server_path);

        // Check if the server is blacklisted
        $blacklisted_records = check_blacklist($server_path);

        if (!empty($blacklisted_records)) {
            // Update the server status to inactive
            $update_query = "UPDATE evp_multi_server SET status = 'inactive' WHERE server_path = '$server_path'";
            $db->update($update_query);

            // Prepare email notification
            $subject = "Server Blacklisted: $server_path";
            $message = "<h1>Blacklist Report for $server_path</h1>";
            $message .= "<table border='1'><tr><th>Type</th><th>DNS Zone</th></tr>";
            foreach ($blacklisted_records as $record) {
                $message .= "<tr><td>{$record['type']}</td><td>{$record['dns_zone']}</td></tr>";
            }
            $message .= "</table>";

            // Send email notification
            if ($mailer->sendMail($system_email, $subject, $message)) {
                $log->system_debug('Server marked as inactive and email sent: ' . $server_path);
            } else {
                $log->system_debug('Failed to send email for server: ' . $server_path);
            }
        }
    }
} else {
    $log->system_debug('No active servers found');
}

$log->system_debug('Blacklist monitoring script completed');

/**
 * Check if a server is blacklisted
 *
 * @param string $server_path
 * @return array
 */
function check_blacklist($server_path) {
    global $log, $db;

    $resolver = new Net_DNS2_Resolver(array(
        'nameservers' => array('208.67.222.222'),
        'timeout' => 5 // Set timeout to 5 seconds
    ));
    $ip_address = gethostbyname($server_path);
    $reverse_ip = implode(".", array_reverse(explode(".", $ip_address)));

    // Fetch DNSBL zones from the database
    $dnsbl_query = "SELECT dnszone, type FROM evp_dnsbl";
    $dnsbl_result = $db->select($dnsbl_query);

    if ($dnsbl_result->num_rows === 0) {
        $log->system_debug('No DNSBL zones found in the database');
        return [];
    }

    $blacklisted_records = [];

    while ($dnsbl = $dnsbl_result->fetch_assoc()) {
        $dnsr = ($dnsbl['type'] === 'IP') ? $reverse_ip . "." . $dnsbl['dnszone'] : $server_path . "." . $dnsbl['dnszone'];

        try {
            $response = $resolver->query($dnsr, "A");
            if (count($response->answer) > 0) {
                foreach ($response->answer as $rr) {
                    if ($rr->address) {
                        $log->system_debug('Server blacklisted: ' . $server_path . ' in ' . $dnsbl['dnszone']);
                        $blacklisted_records[] = [
                            'server_path' => $server_path,
                            'dns_zone' => $dnsbl['dnszone'],
                            'type' => $dnsbl['type']
                        ];
                    }
                }
            }
        } catch (Net_DNS2_Exception $e) {
            // Only log severe DNS errors (not NXDOMAIN)
            if ($e->getCode() != Net_DNS2_Lookups::RCODE_NXDOMAIN) {
                $log->system_debug('DNS query severe error for ' . $dnsr . ': ' . $e->getMessage());
            }
            // Do not log NXDOMAIN (domain does not exist) to reduce log noise
        }
    }

    return $blacklisted_records;
}
?>
