<?php

/**
 * UltyScan Web Interface - Comprehensive Report Viewer
 * Compiles all workspace files into a single readable HTML report
 */

$name = preg_replace('/[^a-zA-Z0-9\-\_\.]/', '', $_GET['name'] ?? '');
if (empty($name)) {
    die('Invalid workspace name');
}

$workspaceDir = '/usr/share/sniper/loot/workspace/' . $name;
if (!is_dir($workspaceDir)) {
    die('Workspace not found');
}

// Collect all data from workspace
$report = [
    'name' => $name,
    'created' => date('Y-m-d H:i:s', filectime($workspaceDir)),
    'modified' => date('Y-m-d H:i:s', filemtime($workspaceDir)),
    'sections' => []
];

// Helper function to read file safely
function readFileContent($path, $maxLines = 500)
{
    if (!file_exists($path) || !is_readable($path)) return null;
    $content = file_get_contents($path);
    if ($content === false) return null;
    // Limit very long files
    $lines = explode("\n", $content);
    if (count($lines) > $maxLines) {
        $content = implode("\n", array_slice($lines, 0, $maxLines));
        $content .= "\n\n... [Truncated - " . (count($lines) - $maxLines) . " more lines]";
    }
    return $content;
}

// Helper to determine file category
function categorizeFile($filename)
{
    $lower = strtolower($filename);
    if (strpos($lower, 'nmap') !== false) return 'Port Scans';
    if (strpos($lower, 'nuclei') !== false) return 'Vulnerability Findings';
    if (strpos($lower, 'nikto') !== false) return 'Web Server Analysis';
    if (strpos($lower, 'whatweb') !== false) return 'Technology Detection';
    if (strpos($lower, 'dns') !== false || strpos($lower, 'subdomain') !== false) return 'DNS & Subdomains';
    if (strpos($lower, 'whois') !== false) return 'WHOIS Information';
    if (strpos($lower, 'ssl') !== false || strpos($lower, 'cert') !== false) return 'SSL/TLS Analysis';
    if (strpos($lower, 'dir') !== false || strpos($lower, 'brute') !== false) return 'Directory Discovery';
    if (strpos($lower, 'host') !== false) return 'Host Information';
    if (strpos($lower, 'osint') !== false) return 'OSINT Data';
    if (strpos($lower, 'screenshot') !== false) return 'Screenshots';
    return 'Other Findings';
}

// Recursively scan workspace
function scanWorkspaceFiles($dir, $prefix = '')
{
    $files = [];
    if (!is_dir($dir)) return $files;

    $items = scandir($dir);
    foreach ($items as $item) {
        if ($item === '.' || $item === '..') continue;
        $path = $dir . '/' . $item;
        $relativePath = $prefix . $item;

        if (is_dir($path)) {
            $files = array_merge($files, scanWorkspaceFiles($path, $relativePath . '/'));
        } else {
            $ext = strtolower(pathinfo($item, PATHINFO_EXTENSION));
            // Skip binary and image files for content reading
            $skipExtensions = ['png', 'jpg', 'jpeg', 'gif', 'pdf', 'zip', 'tar', 'gz', 'exe', 'bin'];

            $files[] = [
                'path' => $relativePath,
                'fullPath' => $path,
                'name' => $item,
                'size' => filesize($path),
                'category' => categorizeFile($relativePath),
                'extension' => $ext,
                'isImage' => in_array($ext, ['png', 'jpg', 'jpeg', 'gif']),
                'isBinary' => in_array($ext, $skipExtensions)
            ];
        }
    }
    return $files;
}

$allFiles = scanWorkspaceFiles($workspaceDir);

// Group files by category
$categorized = [];
foreach ($allFiles as $file) {
    $cat = $file['category'];
    if (!isset($categorized[$cat])) {
        $categorized[$cat] = [];
    }
    $categorized[$cat][] = $file;
}

// Priority order for sections
$sectionOrder = [
    'Host Information',
    'Port Scans',
    'Vulnerability Findings',
    'Web Server Analysis',
    'Technology Detection',
    'SSL/TLS Analysis',
    'DNS & Subdomains',
    'Directory Discovery',
    'WHOIS Information',
    'OSINT Data',
    'Screenshots',
    'Other Findings'
];

// Generate unique ID for TOC
$sectionId = 0;
?>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>UltyScan Report - <?php echo htmlspecialchars($name); ?></title>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
    <style>
        :root {
            --bg-primary: #0f1419;
            --bg-secondary: #1a1f2e;
            --bg-tertiary: #242938;
            --bg-code: #0d1117;
            --accent-primary: #3b82f6;
            --accent-secondary: #8b5cf6;
            --accent-success: #10b981;
            --accent-warning: #f59e0b;
            --accent-danger: #ef4444;
            --accent-info: #06b6d4;
            --text-primary: #e6edf3;
            --text-secondary: #8b949e;
            --text-muted: #6e7681;
            --border-color: #30363d;
            --border-accent: #388bfd;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Inter', -apple-system, sans-serif;
            background: var(--bg-primary);
            color: var(--text-primary);
            line-height: 1.6;
        }

        .container {
            max-width: 1600px;
            margin: 0 auto;
            display: grid;
            grid-template-columns: 280px 1fr;
            min-height: 100vh;
        }

        /* Sidebar / Table of Contents */
        .sidebar {
            position: sticky;
            top: 0;
            height: 100vh;
            overflow-y: auto;
            background: var(--bg-secondary);
            border-right: 1px solid var(--border-color);
            padding: 1.5rem;
        }

        .sidebar-header {
            padding-bottom: 1rem;
            border-bottom: 1px solid var(--border-color);
            margin-bottom: 1rem;
        }

        .sidebar-header h1 {
            font-size: 1.25rem;
            background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            margin-bottom: 0.25rem;
        }

        .sidebar-header .meta {
            font-size: 0.75rem;
            color: var(--text-secondary);
        }

        .toc-section {
            margin-bottom: 1rem;
        }

        .toc-title {
            font-size: 0.7rem;
            text-transform: uppercase;
            letter-spacing: 0.05em;
            color: var(--text-muted);
            margin-bottom: 0.5rem;
            font-weight: 600;
        }

        .toc-link {
            display: block;
            padding: 0.4rem 0.75rem;
            color: var(--text-secondary);
            text-decoration: none;
            border-radius: 6px;
            font-size: 0.85rem;
            transition: all 0.15s;
            margin-bottom: 2px;
        }

        .toc-link:hover {
            background: var(--bg-tertiary);
            color: var(--text-primary);
        }

        .toc-link .count {
            float: right;
            font-size: 0.75rem;
            background: var(--bg-tertiary);
            padding: 0.1rem 0.4rem;
            border-radius: 10px;
        }

        /* Main Content */
        .main-content {
            padding: 2rem 3rem;
            overflow-x: hidden;
        }

        .report-header {
            margin-bottom: 2rem;
            padding-bottom: 1.5rem;
            border-bottom: 1px solid var(--border-color);
        }

        .report-header h1 {
            font-size: 2rem;
            margin-bottom: 0.5rem;
        }

        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 1rem;
            margin-bottom: 2rem;
        }

        .stat-card {
            background: var(--bg-secondary);
            border: 1px solid var(--border-color);
            border-radius: 8px;
            padding: 1rem;
            text-align: center;
        }

        .stat-card .number {
            font-size: 1.75rem;
            font-weight: 700;
            color: var(--accent-primary);
        }

        .stat-card .label {
            font-size: 0.8rem;
            color: var(--text-secondary);
        }

        /* Sections */
        .section {
            margin-bottom: 2.5rem;
            scroll-margin-top: 1rem;
        }

        .section-header {
            display: flex;
            align-items: center;
            gap: 0.75rem;
            margin-bottom: 1rem;
            padding-bottom: 0.75rem;
            border-bottom: 2px solid var(--border-color);
        }

        .section-header h2 {
            font-size: 1.25rem;
            color: var(--text-primary);
        }

        .section-icon {
            width: 28px;
            height: 28px;
            border-radius: 6px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 0.9rem;
        }

        .section-icon.port {
            background: rgba(59, 130, 246, 0.2);
        }

        .section-icon.vuln {
            background: rgba(239, 68, 68, 0.2);
        }

        .section-icon.web {
            background: rgba(16, 185, 129, 0.2);
        }

        .section-icon.dns {
            background: rgba(139, 92, 246, 0.2);
        }

        .section-icon.ssl {
            background: rgba(245, 158, 11, 0.2);
        }

        .section-icon.other {
            background: rgba(107, 114, 128, 0.2);
        }

        /* File Cards */
        .file-card {
            background: var(--bg-secondary);
            border: 1px solid var(--border-color);
            border-radius: 8px;
            margin-bottom: 1rem;
            overflow: hidden;
        }

        .file-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 0.75rem 1rem;
            background: var(--bg-tertiary);
            border-bottom: 1px solid var(--border-color);
            cursor: pointer;
        }

        .file-header:hover {
            background: #2d3548;
        }

        .file-name {
            font-family: 'JetBrains Mono', monospace;
            font-size: 0.85rem;
            color: var(--accent-info);
        }

        .file-meta {
            font-size: 0.75rem;
            color: var(--text-muted);
        }

        .file-content {
            padding: 1rem;
            max-height: 600px;
            overflow-y: auto;
        }

        .file-content pre {
            font-family: 'JetBrains Mono', monospace;
            font-size: 0.8rem;
            line-height: 1.5;
            white-space: pre-wrap;
            word-break: break-word;
            color: var(--text-primary);
            margin: 0;
        }

        /* Syntax highlighting for common patterns */
        .highlight-ip {
            color: #79c0ff;
        }

        .highlight-port {
            color: #a5d6ff;
        }

        .highlight-vuln {
            color: #ffa657;
        }

        .highlight-critical {
            color: #ff7b72;
        }

        .highlight-success {
            color: #7ee787;
        }

        .highlight-info {
            color: #a371f7;
        }

        /* Image section */
        .screenshot-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
            gap: 1rem;
        }

        .screenshot-card {
            background: var(--bg-secondary);
            border: 1px solid var(--border-color);
            border-radius: 8px;
            overflow: hidden;
        }

        .screenshot-card img {
            width: 100%;
            height: 200px;
            object-fit: cover;
            cursor: pointer;
            transition: transform 0.2s;
        }

        .screenshot-card img:hover {
            transform: scale(1.02);
        }

        .screenshot-caption {
            padding: 0.75rem;
            font-size: 0.8rem;
            color: var(--text-secondary);
            background: var(--bg-tertiary);
        }

        /* Empty state */
        .empty-section {
            text-align: center;
            padding: 2rem;
            color: var(--text-muted);
            font-style: italic;
        }

        /* Print styles */
        @media print {
            .sidebar {
                display: none;
            }

            .container {
                display: block;
            }

            body {
                background: white;
                color: black;
            }

            .file-card {
                break-inside: avoid;
            }
        }

        /* Collapsible */
        .collapsed .file-content {
            display: none;
        }

        .toggle-icon {
            transition: transform 0.2s;
        }

        .collapsed .toggle-icon {
            transform: rotate(-90deg);
        }

        /* Actions */
        .actions {
            display: flex;
            gap: 0.5rem;
            margin-bottom: 1.5rem;
        }

        .btn {
            padding: 0.5rem 1rem;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 0.85rem;
            font-weight: 500;
            transition: all 0.15s;
        }

        .btn-primary {
            background: var(--accent-primary);
            color: white;
        }

        .btn-secondary {
            background: var(--bg-tertiary);
            color: var(--text-primary);
            border: 1px solid var(--border-color);
        }

        .btn:hover {
            opacity: 0.9;
        }
    </style>
</head>

<body>
    <div class="container">
        <!-- Sidebar / Table of Contents -->
        <aside class="sidebar">
            <div class="sidebar-header">
                <h1>🔍 UltyScan Report</h1>
                <div class="meta"><?php echo htmlspecialchars($name); ?></div>
                <div class="meta"><?php echo $report['modified']; ?></div>
            </div>

            <nav class="toc">
                <div class="toc-section">
                    <div class="toc-title">Sections</div>
                    <?php foreach ($sectionOrder as $section): ?>
                        <?php if (isset($categorized[$section])): ?>
                            <a href="#section-<?php echo $sectionId++; ?>" class="toc-link">
                                <?php echo $section; ?>
                                <span class="count"><?php echo count($categorized[$section]); ?></span>
                            </a>
                        <?php endif; ?>
                    <?php endforeach; ?>
                </div>
            </nav>
        </aside>

        <!-- Main Content -->
        <main class="main-content">
            <header class="report-header">
                <h1><?php echo htmlspecialchars($name); ?></h1>
                <p style="color: var(--text-secondary);">
                    Generated: <?php echo $report['created']; ?> |
                    Last Modified: <?php echo $report['modified']; ?>
                </p>
            </header>

            <div class="stats-grid">
                <div class="stat-card">
                    <div class="number"><?php echo count($allFiles); ?></div>
                    <div class="label">Total Files</div>
                </div>
                <div class="stat-card">
                    <div class="number"><?php echo count($categorized); ?></div>
                    <div class="label">Categories</div>
                </div>
                <div class="stat-card">
                    <div class="number"><?php
                                        $total = 0;
                                        foreach ($allFiles as $f) $total += $f['size'];
                                        echo number_format($total / 1024, 1);
                                        ?> KB</div>
                    <div class="label">Total Size</div>
                </div>
            </div>

            <div class="actions">
                <button class="btn btn-primary" onclick="expandAll()">Expand All</button>
                <button class="btn btn-secondary" onclick="collapseAll()">Collapse All</button>
                <button class="btn btn-secondary" onclick="window.print()">Print Report</button>
            </div>

            <?php
            $sectionId = 0;
            foreach ($sectionOrder as $section):
                if (!isset($categorized[$section])) continue;
                $files = $categorized[$section];
                $iconClass = 'other';
                if (strpos($section, 'Port') !== false) $iconClass = 'port';
                elseif (strpos($section, 'Vuln') !== false) $iconClass = 'vuln';
                elseif (strpos($section, 'Web') !== false) $iconClass = 'web';
                elseif (strpos($section, 'DNS') !== false) $iconClass = 'dns';
                elseif (strpos($section, 'SSL') !== false) $iconClass = 'ssl';
            ?>
                <section class="section" id="section-<?php echo $sectionId++; ?>">
                    <div class="section-header">
                        <span class="section-icon <?php echo $iconClass; ?>">
                            <?php
                            echo match ($iconClass) {
                                'port' => '🔌',
                                'vuln' => '⚠️',
                                'web' => '🌐',
                                'dns' => '🔍',
                                'ssl' => '🔒',
                                default => '📄'
                            };
                            ?>
                        </span>
                        <h2><?php echo $section; ?></h2>
                    </div>

                    <?php if ($section === 'Screenshots'): ?>
                        <div class="screenshot-grid">
                            <?php foreach ($files as $file): ?>
                                <?php if ($file['isImage']): ?>
                                    <div class="screenshot-card">
                                        <img src="/loot/workspace/<?php echo urlencode($name); ?>/<?php echo $file['path']; ?>"
                                            alt="<?php echo htmlspecialchars($file['name']); ?>"
                                            onclick="window.open(this.src, '_blank')">
                                        <div class="screenshot-caption"><?php echo htmlspecialchars($file['name']); ?></div>
                                    </div>
                                <?php endif; ?>
                            <?php endforeach; ?>
                        </div>
                    <?php else: ?>
                        <?php foreach ($files as $file): ?>
                            <?php if ($file['isBinary']): continue;
                            endif; ?>
                            <?php $content = readFileContent($file['fullPath']); ?>
                            <?php if ($content === null || trim($content) === ''): continue;
                            endif; ?>

                            <div class="file-card">
                                <div class="file-header" onclick="this.parentElement.classList.toggle('collapsed')">
                                    <div>
                                        <span class="file-name"><?php echo htmlspecialchars($file['path']); ?></span>
                                    </div>
                                    <div class="file-meta">
                                        <?php echo number_format($file['size'] / 1024, 1); ?> KB
                                        <span class="toggle-icon">▼</span>
                                    </div>
                                </div>
                                <div class="file-content">
                                    <pre><?php echo htmlspecialchars($content); ?></pre>
                                </div>
                            </div>
                        <?php endforeach; ?>
                    <?php endif; ?>
                </section>
            <?php endforeach; ?>
        </main>
    </div>

    <script>
        function expandAll() {
            document.querySelectorAll('.file-card').forEach(card => {
                card.classList.remove('collapsed');
            });
        }

        function collapseAll() {
            document.querySelectorAll('.file-card').forEach(card => {
                card.classList.add('collapsed');
            });
        }

        // Start with files collapsed for faster loading
        document.addEventListener('DOMContentLoaded', () => {
            collapseAll();
        });
    </script>
</body>

</html>