<?php

/**
 * UltyScan Web Interface - Execute Scan
 * Handles form submissions and runs the sniper command
 */

header('Content-Type: application/json');

// Security: Only allow POST requests
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['success' => false, 'error' => 'Method not allowed']);
    exit;
}

// Configuration
define('SNIPER_PATH', 'sudo bash /usr/share/sniper/sniper');
define('LOG_DIR', '/var/log/ultyscan');

// Ensure log directory exists
if (!is_dir(LOG_DIR)) {
    mkdir(LOG_DIR, 0755, true);
}

// Handle special actions
$action = $_POST['action'] ?? '';

if ($action === 'update') {
    $installDir = '/usr/share/sniper';
    $webDir = '/var/www/html/ultyscan';
    $logFile = LOG_DIR . '/update_' . date('Ymd_His') . '.log';

    // Commands to update
    $commands = [
        "cd $installDir && git fetch origin",
        "cd $installDir && git reset --hard origin/main",
        "cd $installDir && git pull origin main",
        "cp -r $installDir/webui/* $webDir/",
        "chown -R www-data:www-data $webDir",
        // Create .version file with git info
        "cd $installDir && git rev-parse --short HEAD > $webDir/.version",
        "cd $installDir && git rev-parse HEAD >> $webDir/.version",
        "cd $installDir && git rev-parse --abbrev-ref HEAD >> $webDir/.version",
        "cd $installDir && git log -1 --format=%ci >> $webDir/.version",
        "chown www-data:www-data $webDir/.version"
    ];

    $output = [];
    $output[] = "UltyScan Update - " . date('Y-m-d H:i:s');
    $output[] = str_repeat('-', 40);

    foreach ($commands as $cmd) {
        $output[] = "$ $cmd";
        $cmdOutput = shell_exec($cmd . ' 2>&1');
        if ($cmdOutput) {
            $output[] = trim($cmdOutput);
        }
    }

    $output[] = str_repeat('-', 40);
    $output[] = "Update completed at " . date('Y-m-d H:i:s');

    // Get new commit info
    $newCommit = trim(shell_exec("cd $installDir && git rev-parse --short HEAD 2>/dev/null"));
    $output[] = "Now at commit: $newCommit";

    // Write log
    file_put_contents($logFile, implode("\n", $output));

    echo json_encode([
        'success' => true,
        'message' => 'Update completed',
        'commit' => $newCommit,
        'log' => $logFile,
        'output' => implode("\n", $output)
    ]);
    exit;
}

if ($action === 'stop') {
    exec('pkill -f "sniper"');
    echo json_encode(['success' => true, 'message' => 'Stop signal sent']);
    exit;
}

// Build the sniper command
$command = SNIPER_PATH;
$errors = [];

// Target (required unless using file)
$target = trim($_POST['target'] ?? '');
$targetFile = trim($_POST['target_file'] ?? '');
$mode = trim($_POST['mode'] ?? 'normal');

// Validate mode against allowed list
$allowedModes = [
    'normal',
    'stealth',
    'web',
    'webscan',
    'webporthttp',
    'webporthttps',
    'port',
    'fullportonly',
    'discover',
    'flyover',
    'airstrike',
    'nuke',
    'massportscan',
    'massweb',
    'masswebscan',
    'massvulnscan'
];

if (!in_array($mode, $allowedModes)) {
    echo json_encode(['success' => false, 'error' => 'Invalid scan mode']);
    exit;
}

// Modes that require a file instead of single target
$fileModes = ['airstrike', 'nuke', 'massportscan', 'massweb', 'masswebscan', 'massvulnscan', 'flyover'];

if (in_array($mode, $fileModes)) {
    if (empty($targetFile)) {
        echo json_encode(['success' => false, 'error' => 'This mode requires a target file']);
        exit;
    }
    // Write targets to temp file
    $tmpFile = '/tmp/ultyscan_targets_' . uniqid() . '.txt';
    file_put_contents($tmpFile, $targetFile);
    $command .= ' -f ' . escapeshellarg($tmpFile);
} else {
    if (empty($target)) {
        echo json_encode(['success' => false, 'error' => 'Target is required']);
        exit;
    }
    // Sanitize target
    $target = preg_replace('/[^a-zA-Z0-9\.\-\_\/\:]/', '', $target);
    $command .= ' -t ' . escapeshellarg($target);
}

// Mode
$command .= ' -m ' . escapeshellarg($mode);

// Workspace
$workspace = trim($_POST['workspace'] ?? '');
if (!empty($workspace)) {
    $workspace = preg_replace('/[^a-zA-Z0-9\-\_]/', '', $workspace);
    $command .= ' -w ' . escapeshellarg($workspace);
}

// Port (for port modes)
$port = intval($_POST['port'] ?? 0);
if ($port > 0 && $port <= 65535) {
    $command .= ' -p ' . $port;
}

// Options
if (!empty($_POST['osint'])) {
    $command .= ' -o';
}

if (!empty($_POST['recon'])) {
    $command .= ' -re';
}

if (!empty($_POST['bruteforce'])) {
    $command .= ' -b';
}

if (!empty($_POST['fullportscan'])) {
    $command .= ' -fp';
}

// Create log file for this scan
$scanId = date('Ymd_His') . '_' . substr(md5(uniqid()), 0, 6);
$logFile = LOG_DIR . '/scan_' . $scanId . '.log';

// Run the command in background
$fullCommand = "nohup $command > $logFile 2>&1 &";

// Log the command (for debugging)
file_put_contents(LOG_DIR . '/commands.log', date('Y-m-d H:i:s') . " - $command\n", FILE_APPEND);

// Execute
exec($fullCommand);

echo json_encode([
    'success' => true,
    'scanId' => $scanId,
    'command' => $command,
    'logFile' => $logFile,
    'message' => 'Scan started'
]);
