import { NextRequest, NextResponse } from 'next/server' import { exec } from 'child_process' import { promisify } from 'util' import fs from 'fs/promises' const execAsync = promisify(exec) export async function GET() { try { // Get server statistics const stats = await Promise.all([ getCPUUsage(), getMemoryUsage(), getDiskUsage(), getNetworkStats(), getCSFStats(), getSystemUptime() ]) const [cpu, memory, disk, network, csf, uptime] = stats return NextResponse.json({ success: true, data: { cpu_usage: cpu, memory_usage: memory, disk_usage: disk, network: network, csf_stats: csf, uptime: uptime, timestamp: new Date().toISOString() } }) } catch (error: any) { console.error('Stats API error:', error) return NextResponse.json({ success: false, error: `Failed to retrieve statistics: ${error.message}` }, { status: 500 }) } } async function getCPUUsage(): Promise { try { // Get CPU usage from /proc/loadavg const { stdout } = await execAsync('cat /proc/loadavg') const loadAvg = parseFloat(stdout.split(' ')[0]) // Convert to percentage (assuming single core, adjust for multi-core) const { stdout: cpuInfo } = await execAsync('nproc') const cores = parseInt(cpuInfo.trim()) return Math.min((loadAvg / cores) * 100, 100) } catch { return 0 } } async function getMemoryUsage(): Promise<{ used: number; total: number; percentage: number }> { try { const { stdout } = await execAsync('free -b') const lines = stdout.split('\\n') const memLine = lines[1].split(/\\s+/) const total = parseInt(memLine[1]) const used = parseInt(memLine[2]) const percentage = (used / total) * 100 return { used, total, percentage: Math.round(percentage * 100) / 100 } } catch { return { used: 0, total: 0, percentage: 0 } } } async function getDiskUsage(): Promise<{ used: number; total: number; percentage: number }> { try { const { stdout } = await execAsync('df -B1 / | tail -1') const parts = stdout.split(/\\s+/) const total = parseInt(parts[1]) const used = parseInt(parts[2]) const percentage = (used / total) * 100 return { used, total, percentage: Math.round(percentage * 100) / 100 } } catch { return { used: 0, total: 0, percentage: 0 } } } async function getNetworkStats(): Promise<{ in_bytes: number; out_bytes: number; connections: number }> { try { // Get network interface stats const { stdout } = await execAsync('cat /proc/net/dev | grep -E "(eth0|ens|enp)" | head -1') if (stdout) { const parts = stdout.split(/\\s+/) const inBytes = parseInt(parts[1]) || 0 const outBytes = parseInt(parts[9]) || 0 // Get active connections const { stdout: connStdout } = await execAsync('netstat -tn | grep ESTABLISHED | wc -l') const connections = parseInt(connStdout.trim()) || 0 return { in_bytes: inBytes, out_bytes: outBytes, connections } } return { in_bytes: 0, out_bytes: 0, connections: 0 } } catch { return { in_bytes: 0, out_bytes: 0, connections: 0 } } } async function getCSFStats(): Promise<{ status: string; blocked_ips: number; allowed_ips: number; temp_blocks: number; rules_count: number; }> { try { // Check CSF status let status = 'unknown' try { await execAsync('/usr/local/csf/bin/csf --status >/dev/null 2>&1') status = 'active' } catch { status = 'inactive' } // Count rules in files let blockedIps = 0 let allowedIps = 0 let tempBlocks = 0 try { const denyContent = await fs.readFile('/etc/csf/csf.deny', 'utf-8') blockedIps = denyContent.split('\\n').filter(line => line.trim() && !line.trim().startsWith('#') ).length } catch {} try { const allowContent = await fs.readFile('/etc/csf/csf.allow', 'utf-8') allowedIps = allowContent.split('\\n').filter(line => line.trim() && !line.trim().startsWith('#') ).length } catch {} try { const { stdout } = await execAsync('/usr/local/csf/bin/csf --temp 2>/dev/null | grep -c "Temporary" || echo "0"') tempBlocks = parseInt(stdout.trim()) || 0 } catch {} return { status, blocked_ips: blockedIps, allowed_ips: allowedIps, temp_blocks: tempBlocks, rules_count: blockedIps + allowedIps } } catch { return { status: 'unknown', blocked_ips: 0, allowed_ips: 0, temp_blocks: 0, rules_count: 0 } } } async function getSystemUptime(): Promise { try { const { stdout } = await execAsync('cat /proc/uptime') const uptime = parseFloat(stdout.split(' ')[0]) return Math.floor(uptime) } catch { return 0 } } // Real-time stats endpoint export async function POST(request: NextRequest) { try { const body = await request.json() const { interval = 5000 } = body // Default 5 seconds // This would typically be handled by WebSocket // For now, return current stats const stats = await GET() const response = await stats.json() return NextResponse.json({ success: true, data: { ...response.data, interval, next_update: Date.now() + interval } }) } catch (error: any) { return NextResponse.json({ success: false, error: `Failed to get real-time stats: ${error.message}` }, { status: 500 }) } }