<?php
// Production-Ready Code Execution for cPanel
// Uses Piston API - No local compilation required!
// Free, fast, and secure cloud-based code execution

// Only start session if not already started
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

// Set execution time limit
set_time_limit(30);
ini_set('max_execution_time', '30');

// Set headers
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');

// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

// Rate limiting function
function checkRateLimit() {
    if (!isset($_SESSION['user_id'])) {
        echo json_encode(['success' => false, 'output' => 'Authentication required']);
        exit();
    }

    $user_id = $_SESSION['user_id'];
    $rate_limit_file = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'rate_limit_' . $user_id . '.json';

    $current_time = time();
    $rate_data = [];

    if (file_exists($rate_limit_file)) {
        $rate_data = json_decode(file_get_contents($rate_limit_file), true) ?: [];
        $rate_data = array_filter($rate_data, function($timestamp) use ($current_time) {
            return ($current_time - $timestamp) < 60;
        });
    }

    // Allow 15 requests per minute for better user experience
    if (count($rate_data) >= 15) {
        $oldest_request = min($rate_data);
        $wait_time = 60 - ($current_time - $oldest_request);
        echo json_encode([
            'success' => false,
            'output' => "Rate limit exceeded! Please wait {$wait_time} seconds before trying again.\nMaximum 15 code executions per minute."
        ]);
        exit();
    }

    $rate_data[] = $current_time;
    file_put_contents($rate_limit_file, json_encode($rate_data));
}

checkRateLimit();

// Filter input prompts from output
function filterInputPrompts($output) {
    $output = preg_replace('/(Enter|Input|Type|Provide|Please\s+enter)\s+[^:\n]+:\s*/i', '', $output);
    $lines = explode("\n", $output);
    $filtered_lines = [];

    foreach ($lines as $line) {
        $trimmed = trim($line);
        if (!empty($trimmed)) {
            $filtered_lines[] = $line;
        }
    }

    return implode("\n", $filtered_lines);
}

// Validate request method
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    echo json_encode(['success' => false, 'output' => 'Invalid request method']);
    exit();
}

// Get request data
$code = $_POST['code'] ?? '';
$language = $_POST['language'] ?? 'cpp';
$input = $_POST['input'] ?? '';

if (empty($code)) {
    echo json_encode(['success' => false, 'output' => 'No code provided']);
    exit();
}

// Piston API Configuration
$PISTON_API_URL = 'https://emkc.org/api/v2/piston/execute';

// Map language to Piston language identifier
$language_map = [
    'cpp' => 'c++',
    'c++' => 'c++',
    'c' => 'c'
];

$piston_language = $language_map[$language] ?? 'c++';

// Determine file extension
$file_extension = ($language === 'c') ? 'c' : 'cpp';

// Prepare request data for Piston API
$request_data = [
    'language' => $piston_language,
    'version' => ($piston_language === 'c') ? '10.2.0' : '10.2.0', // GCC version
    'files' => [
        [
            'name' => 'main.' . $file_extension,
            'content' => $code
        ]
    ],
    'stdin' => $input,
    'args' => [],
    'compile_timeout' => 10000, // 10 seconds
    'run_timeout' => 5000, // 5 seconds
    'compile_memory_limit' => -1,
    'run_memory_limit' => -1
];

// Initialize cURL
$ch = curl_init();

curl_setopt_array($ch, [
    CURLOPT_URL => $PISTON_API_URL,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS => json_encode($request_data),
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json'
    ],
]);

// Execute request
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curl_error = curl_error($ch);

curl_close($ch);

// Handle cURL errors
if ($curl_error) {
    echo json_encode([
        'success' => false,
        'output' => 'Network error: ' . $curl_error . '\n\nPlease check your internet connection.'
    ]);
    exit();
}

// Handle HTTP errors
if ($http_code !== 200) {
    echo json_encode([
        'success' => false,
        'output' => 'API Error (HTTP ' . $http_code . '). The code execution service is temporarily unavailable. Please try again in a moment.'
    ]);
    exit();
}

// Parse API response
$result = json_decode($response, true);

if (!$result) {
    echo json_encode([
        'success' => false,
        'output' => 'Failed to parse API response. Please try again.'
    ]);
    exit();
}

// Process the result
$output = '';
$success = false;

// Check compilation result
if (isset($result['compile']) && !empty($result['compile']['stderr'])) {
    // Compilation error
    $output = "Compilation Error:\n" . trim($result['compile']['stderr']);

    // Clean up common GCC error formatting
    $output = preg_replace('/main\.(cpp|c):/i', 'Line ', $output);

} elseif (isset($result['run'])) {
    // Check runtime result
    $run_result = $result['run'];

    if (!empty($run_result['stdout'])) {
        // Success - has output
        $success = true;
        $output = trim($run_result['stdout']);

        // Filter input prompts if input was provided
        if (!empty($input)) {
            $output = filterInputPrompts($output);
        }

    } elseif (!empty($run_result['stderr'])) {
        // Runtime error
        $output = "Runtime Error:\n" . trim($run_result['stderr']);

    } elseif ($run_result['code'] === 0) {
        // Success but no output
        $success = true;
        $output = '(Program executed successfully but produced no output)';

    } else {
        // Other error
        $output = "Error: Program exited with code " . $run_result['code'];
        if (!empty($run_result['stderr'])) {
            $output .= "\n" . trim($run_result['stderr']);
        }
    }
} else {
    $output = 'Unexpected API response. Please try again.';
}

// Return final response
echo json_encode([
    'success' => $success,
    'output' => $output,
    'type' => $success ? 'success' : 'error',
    'language' => $piston_language,
    'version' => $result['version'] ?? '10.2.0'
]);
?>
