<?php
/**
 * Lucas IT Services - WHOIS & Registry Lookup
 * Path: /var/www/html/tools/who-reg/index.php
 */

declare(strict_types=1);

session_start();

// Read theme preference directly from cookie for SSR consistency
$current_theme = $_COOKIE['theme'] ?? 'dark';
if (!in_array($current_theme, ['dark', 'light'], true)) {
    $current_theme = 'dark';
}

// Generate CSRF token if not present
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

$json_data = null;
$error_msg = "";

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $posted_token = $_POST['csrf_token'] ?? '';
    if (!hash_equals($_SESSION['csrf_token'], $posted_token)) {
        $error_msg = "Invalid session token. Please refresh the page and try again.";
    } else {
        $target_raw = $_POST['target'] ?? '';
        
        // Strip scheme, path, and port before performing structural validation
        $cleaned = preg_replace('#^https?://#i', '', trim((string)$target_raw));
        $cleaned = explode('/', $cleaned)[0];
        $cleaned = explode(':', $cleaned)[0];
        $target  = trim($cleaned);

        if (strlen($target) < 1 || strlen($target) > 253) {
            $error_msg = "Input length must be between 1 and 253 characters.";
        } else {
            $is_ipv4   = filter_var($target, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;
            $is_ipv6   = filter_var($target, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false;
            $is_domain = preg_match('/^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/', $target) === 1;

            if (!$is_ipv4 && !$is_ipv6 && !$is_domain) {
                $error_msg = "Please enter a valid IPv4 address, IPv6 address, or domain name.";
            }
        }

        if (empty($error_msg) && !empty($target)) {
            $script_path = "../cgi-bin/check-host.py";
            if (!is_executable($script_path)) {
                $error_msg = "Backend WHOIS lookup engine is unavailable or unexecutable.";
            } else {
                $cmd_used = sprintf('%s %s', $script_path, escapeshellarg($target));
                
                $descriptors = [
                    0 => ['pipe', 'r'],
                    1 => ['pipe', 'w'],
                    2 => ['pipe', 'w']
                ];

                $process = proc_open($cmd_used, $descriptors, $pipes);

                if (is_resource($process)) {
                    fclose($pipes[0]);
                    
                    stream_set_blocking($pipes[1], false);
                    stream_set_blocking($pipes[2], false);

                    $stdoutData = '';
                    $stderrData = '';
                    $startTime = time();
                    $timeout = 15;

                    while (true) {
                        $stdoutData .= stream_get_contents($pipes[1]);
                        $stderrData .= stream_get_contents($pipes[2]);

                        $status = proc_get_status($process);
                        if (!$status['running']) {
                            break;
                        }

                        if ((time() - $startTime) > $timeout) {
                            proc_terminate($process, 9);
                            $error_msg = "Error: WHOIS lookup timed out after {$timeout} seconds.";
                            break;
                        }

                        usleep(50000);
                    }

                    fclose($pipes[1]);
                    fclose($pipes[2]);
                    proc_close($process);

                    if (empty($error_msg)) {
                        if (!empty($stdoutData)) {
                            $json_data = json_decode($stdoutData, true);
                            if (json_last_error() !== JSON_ERROR_NONE) {
                                $error_msg = "Failed to parse JSON output from python engine.";
                                $json_data = null;
                            } elseif (isset($json_data['error'])) {
                                $error_msg = $json_data['error'];
                                $json_data = null;
                            }
                        } elseif (!empty($stderrData)) {
                            $error_msg = "Execution Error: " . trim($stderrData);
                        } else {
                            $error_msg = "No output returned from backend script.";
                        }
                    }
                } else {
                    $error_msg = "Failed to execute underlying WHOIS engine.";
                }
            }
        }
    }
}
?>
<!DOCTYPE html>
<html data-theme="<?= htmlspecialchars($current_theme) ?>">
    <head>
        <title>Lucas IT Services - WHOIS &amp; Registry Lookup</title>
        <link rel="icon" type="image/svg+xml" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 50 50'><path fill='%230078d4' fill-rule='evenodd' d='M 25 0 A 24.999868 25.000025 0 0 0 0 25 A 24.999868 25.000025 0 0 0 25 50 A 24.999868 25.000025 0 0 0 50 25 A 24.999868 25.000025 0 0 0 25 0 z M 25 6.9960938 A 18.000229 18.000229 0 0 1 43 24.996094 A 18.000229 18.000229 0 0 1 25 42.996094 A 18.000229 18.000229 0 0 1 7 24.996094 A 18.000229 18.000229 0 0 1 25 6.9960938 z M 21.496094 12 A 0.5 0.5 0 0 0 20.996094 12.5 L 20.996094 25.701172 A 0.5 0.5 0 0 1 20.496094 26.201172 L 11.998047 26.201172 A 0.18766001 0.18766001 0 0 0 11.875 26.529297 L 24.623047 37.669922 A 0.57222682 0.57222682 0 0 0 25.376953 37.669922 L 38.123047 26.529297 A 0.18768046 0.18768046 0 0 0 38 26.201172 L 29.5 26.201172 A 0.5 0.5 0 0 1 29 25.701172 L 29 12.5 A 0.5 0.5 0 0 0 28.5 12 L 21.496094 12 z'/></svg>">
        <link href="../css/style.css" rel="stylesheet" type="text/css">
        <meta charset="UTF-8" />
        <meta name="google" content="notranslate" />
        <meta http-equiv="Content-Language" content="en_US" />
        <style>
            body {
                display: flex;
                flex-direction: column;
                align-items: center;
            }
            .header-bar {
                display: flex;
                justify-content: space-between;
                align-items: flex-start;
                width: 100%;
                max-width: 1050px;
                box-sizing: border-box;
            }
            .page-header {
                display: flex;
                align-items: center;
                gap: 20px;
                margin-bottom: 20px;
            }
            .page-header svg {
                width: 64px;
                height: 64px;
                flex-shrink: 0;
            }
            .page-title {
                margin: 0;
                font-size: 2.25rem;
                font-weight: 700;
            }
            .content-wrapper {
                width: 100%;
                max-width: 1050px;
                box-sizing: border-box;
            }
            .control-row {
                display: flex;
                flex-wrap: wrap;
                align-items: center;
                gap: 10px;
                margin-bottom: 20px;
            }
            .meta-heading {
                margin: 25px 0 15px 0;
                font-size: 1.2rem;
                color: var(--text-main);
            }
            .group-header {
                font-size: 1.3rem;
                font-weight: 700;
                margin: 35px 0 10px 0;
                color: var(--accent);
                border-bottom: 2px solid var(--border-color);
                padding-bottom: 4px;
            }
            .propagation-panel {
                background-color: var(--bg-panel);
                border: 1px solid var(--border-color);
                border-radius: 8px;
                padding: 20px;
                box-shadow: 0 4px 6px rgba(0,0,0,0.2);
                box-sizing: border-box;
                margin-bottom: 20px;
            }
            .propagation-panel table {
                border-collapse: collapse;
                width: 100%;
                table-layout: fixed;
                font-size: 14px;
            }
            .propagation-panel th, .propagation-panel td {
                padding: 10px 12px;
                text-align: left;
                vertical-align: middle;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
                border-bottom: 1px solid var(--border-color);
            }
            .propagation-panel th {
                background-color: #202024;
                color: #fff;
                font-weight: 600;
                border-bottom: 2px solid var(--border-color);
            }
            [data-theme="light"] .propagation-panel th {
                background-color: var(--accent);
            }
            .propagation-panel tr:last-child td {
                border-bottom: none;
            }
            .propagation-panel tr:nth-child(even) td { 
                background-color: var(--table-stripe); 
            }
            .propagation-panel tr:nth-child(odd) td { 
                background-color: var(--table-odd); 
            }
            .propagation-panel tr:hover td { 
                background-color: rgba(0, 0, 0, 0.03); 
            }
            [data-theme="dark"] .propagation-panel tr:hover td { 
                background-color: #29292e; 
            }
            .mono-cell {
                font-family: monospace;
                font-size: 13px;
            }
            .footer-links {
                margin-top: 40px;
                font-size: 14px;
            }
            .footer-links a {
                color: var(--accent);
                text-decoration: none;
            }
            .footer-links a:hover {
                text-decoration: underline;
            }
            .redboxed {
                background-color: rgba(232, 17, 35, 0.1);
                border: 1px solid #e81123;
                color: #f88;
                padding: 12px 16px;
                border-radius: 6px;
                margin-bottom: 20px;
                font-size: 14px;
            }
            [data-theme="light"] .redboxed {
                color: #a00;
            }

            @media (max-width: 768px) {
                .header-bar {
                    flex-direction: column;
                    gap: 15px;
                }
                .control-row {
                    flex-direction: column;
                    align-items: stretch;
                }
                .control-row > * {
                    width: 100% !important;
                }
            }
        </style>
    </head>
    <body>
        <div class="header-bar">
            <div class="page-header">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100%" height="100%">
                    <path fill="var(--accent)" fill-rule="evenodd" d="M 25 0 A 24.999868 25.000025 0 0 0 0 25 A 24.999868 25.000025 0 0 0 25 50 A 24.999868 25.000025 0 0 0 50 25 A 24.999868 25.000025 0 0 0 25 0 z M 25 6.9960938 A 18.000229 18.000229 0 0 1 43 24.996094 A 18.000229 18.000229 0 0 1 25 42.996094 A 18.000229 18.000229 0 0 1 7 24.996094 A 18.000229 18.000229 0 0 1 25 6.9960938 z M 21.496094 12 A 0.5 0.5 0 0 0 20.996094 12.5 L 20.996094 25.701172 A 0.5 0.5 0 0 1 20.496094 26.201172 L 11.998047 26.201172 A 0.18766001 0.18766001 0 0 0 11.875 26.529297 L 24.623047 37.669922 A 0.57222682 0.57222682 0 0 0 25.376953 37.669922 L 38.123047 26.529297 A 0.18768046 0.18768046 0 0 0 38 26.201172 L 29.5 26.201172 A 0.5 0.5 0 0 1 29 25.701172 L 29 12.5 A 0.5 0.5 0 0 0 28.5 12 L 21.496094 12 z" />
                </svg>
                <h1 class="page-title">WHOIS &amp; Registry Lookup</h1>
            </div>
            <div style="margin-top: 15px;">
                <button class="button" id="theme-toggle" type="button">Toggle Theme</button>
            </div>
        </div>

        <div class="content-wrapper">
            <form method="POST">
                <input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
                <div class="control-row">
                    <input type="text" name="target" class="input-field" placeholder="Domain name, IPv4, or IPv6 address"
                        value="<?= htmlspecialchars($_POST['target'] ?? '') ?>"
                        style="width: 380px;" autocomplete="off" required autofocus>
                    
                    <input type="submit" value="Run WHOIS" class="button">
                    <a href="./" class="button">Reset</a>
                </div>
            </form>

            <?php if (!empty($error_msg)): ?>
                <div class="redboxed"><?= htmlspecialchars($error_msg) ?></div>
            <?php endif; ?>

            <?php if ($json_data): ?>
                <h3 class="meta-heading">
                    <strong>Target:</strong> <?= htmlspecialchars($json_data['target'] ?? '') ?> &nbsp;&bull;&nbsp; 
                    <strong>Type:</strong> <?= htmlspecialchars(strtoupper($json_data['type'] ?? '')) ?>
                </h3>

                <?php if (!empty($json_data['dns_records'])): ?>
                    <div class="group-header">DNS Resolution</div>
                    <div class="propagation-panel">
                        <table>
                            <colgroup>
                                <col style="width: 30%;">
                                <col style="width: 70%;">
                            </colgroup>
                            <thead>
                                <tr>
                                    <th>Record Type</th>
                                    <th>Value</th>
                                </tr>
                            </thead>
                            <tbody>
                                <?php foreach ($json_data['dns_records'] as $record): ?>
                                    <tr>
                                        <td><?= htmlspecialchars($record['type']) ?></td>
                                        <td class="mono-cell"><?= htmlspecialchars($record['value']) ?></td>
                                    </tr>
                                <?php endforeach; ?>
                            </tbody>
                        </table>
                    </div>
                <?php endif; ?>

                <?php if (!empty($json_data['registry_info'])): ?>
                    <div class="group-header">RIR Network Registry</div>
                    <div class="propagation-panel">
                        <table>
                            <colgroup>
                                <col style="width: 30%;">
                                <col style="width: 70%;">
                            </colgroup>
                            <thead>
                                <tr>
                                    <th>Property</th>
                                    <th>Details</th>
                                </tr>
                            </thead>
                            <tbody>
                                <?php foreach ($json_data['registry_info'] as $key => $val): ?>
                                    <tr>
                                        <td><?= htmlspecialchars(ucwords(str_replace('_', ' ', $key))) ?></td>
                                        <td class="mono-cell"><?= htmlspecialchars(is_array($val) ? implode(', ', $val) : (string)($val ?? 'N/A')) ?></td>
                                    </tr>
                                <?php endforeach; ?>
                            </tbody>
                        </table>
                    </div>
                <?php endif; ?>

                <?php if (!empty($json_data['domain_whois'])): ?>
                    <div class="group-header">Domain Registration Details</div>
                    <div class="propagation-panel">
                        <table>
                            <colgroup>
                                <col style="width: 30%;">
                                <col style="width: 70%;">
                            </colgroup>
                            <thead>
                                <tr>
                                    <th>Property</th>
                                    <th>Details</th>
                                </tr>
                            </thead>
                            <tbody>
                                <?php foreach ($json_data['domain_whois'] as $key => $val): ?>
                                    <tr>
                                        <td><?= htmlspecialchars(ucwords(str_replace('_', ' ', $key))) ?></td>
                                        <td class="mono-cell"><?= htmlspecialchars(is_array($val) ? implode(', ', $val) : (string)($val ?? 'N/A')) ?></td>
                                    </tr>
                                <?php endforeach; ?>
                            </tbody>
                        </table>
                    </div>
                <?php endif; ?>

            <?php endif; ?>

            <p class="footer-links">
                <a href="index.phps">View Source</a> | <a href="../">Back to Tools</a>
            </p>
        </div>

        <script>
            (function () {
                function setCookie(name, value, days = 365) {
                    const d = new Date();
                    d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
                    document.cookie = name + "=" + value + ";path=/;expires=" + d.toUTCString() + ";SameSite=Lax";
                }

                function getCookie(name) {
                    const nameEQ = name + "=";
                    const ca = document.cookie.split(';');
                    for(let i = 0; i < ca.length; i++) {
                        let c = ca[i].trim();
                        if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
                    }
                    return null;
                }

                let savedTheme = getCookie("theme");
                if (!savedTheme) {
                    savedTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
                }
                document.documentElement.setAttribute("data-theme", savedTheme);

                document.addEventListener("click", function (e) {
                    if (e.target && e.target.id === "theme-toggle") {
                        e.preventDefault();
                        const currentTheme = document.documentElement.getAttribute("data-theme");
                        const newTheme = currentTheme === "dark" ? "light" : "dark";

                        document.documentElement.setAttribute("data-theme", newTheme);
                        setCookie("theme", newTheme);
                    }
                });
            })();
        </script>
    </body>
</html>