<?php
// api/run_r_script.php
session_start();
header('Content-Type: application/json');

require_once '../config.php';
require_once '../includes/auth.php';
require_once '../classes/DataSource.php';

// Get the user details from the session. This relies on your login system.
$user_id = $_SESSION['user_id'] ?? null;
$person_id = $_SESSION['person_id'] ?? null;

// Only allow POST requests and authenticated users with explicit R access.
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || empty($user_id)) {
    http_response_code(401);
    echo json_encode(['status' => 'error', 'message' => 'Unauthorized. Please log in to run this script.']);
    exit();
}

if (!has_r_access()) {
    http_response_code(403);
    echo json_encode(['status' => 'error', 'message' => 'You do not have permission to run R/Jupyter scripts.']);
    exit();
}

if (empty($person_id)) {
    http_response_code(400);
    echo json_encode(['status' => 'error', 'message' => 'Missing user context for R execution.']);
    exit();
}

$dataSourceManager = new DataSource($pdo);

$data = json_decode(file_get_contents('php://input'), true);

if ($data === null) {
    http_response_code(400);
    echo json_encode(['status' => 'error', 'message' => 'Invalid JSON input.']);
    exit();
}

$script_name = $data['script_name'] ?? null;
$data_source_id = isset($data['data_source_id']) ? (int)$data['data_source_id'] : null;
$parameters = $data['parameters'] ?? [];

$r_script_path_dir = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'r_scripts' . DIRECTORY_SEPARATOR;

$allowed_r_scripts = [
    'data_summary.R' => 'Basic Data Summary',
    'descriptive_stats.R' => 'Numeric column descriptive statistics',
    'category_frequency.R' => 'Categorical frequency distribution',
];

if (!isset($allowed_r_scripts[$script_name])) {
    http_response_code(400);
    echo json_encode(['status' => 'error', 'message' => 'Invalid R script selected.']);
    exit();
}

if (empty($data_source_id)) {
    http_response_code(400);
    echo json_encode(['status' => 'error', 'message' => 'Data source ID is required.']);
    exit();
}

try {
    $data_source_details = $dataSourceManager->getDataSourceById($data_source_id);
} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => 'Failed to lookup data source.', 'debug' => $e->getMessage()]);
    exit();
}

if (!$data_source_details) {
    http_response_code(404);
    echo json_encode(['status' => 'error', 'message' => 'Data source not found.']);
    exit();
}

$data_source_owner_person_id = $data_source_details['fkisp_id_of'] ?? null;
$has_access_to_data = ($data_source_owner_person_id && (int)$data_source_owner_person_id === (int)$person_id);

if (!$has_access_to_data) {
    try {
        $has_access_to_data = $dataSourceManager->hasPermission((int)$person_id, $data_source_id, 'Analyze');
    } catch (Exception $e) {
        error_log('Analyze permission check failed: ' . $e->getMessage());
        $has_access_to_data = false;
    }
}

if (!$has_access_to_data) {
    http_response_code(403);
    echo json_encode(['status' => 'error', 'message' => 'You are not allowed to analyze this data source.']);
    exit();
}

$source_filename = $data_source_details['dspsds_filename'] ?? '';
if (empty($source_filename)) {
    http_response_code(400);
    echo json_encode(['status' => 'error', 'message' => 'No associated data file found for this data source.']);
    exit();
}

$upload_dir = $dataSourceManager->getUploadDir();
$upload_dir_real = realpath($upload_dir) ?: $upload_dir;
$full_data_source_path = realpath($upload_dir . $source_filename);

if ($full_data_source_path === false || strpos($full_data_source_path, $upload_dir_real) !== 0 || !is_file($full_data_source_path)) {
    http_response_code(404);
    echo json_encode(['status' => 'error', 'message' => 'Data source file could not be located.']);
    exit();
}

// --- Create a temporary file for the R script to use ---
// This is a security best practice to prevent R from accessing arbitrary files.
$temp_data_file = tempnam(sys_get_temp_dir(), 'rdata_') . '.csv';
copy($full_data_source_path, $temp_data_file);

// Log the usage of the data source
error_log("Logging usage for data source: $data_source_id by user: $user_id for action: Ran Analysis");

// --- Path and Permission Checks ---
$r_executable_path = getenv('RSCRIPT_PATH') ?: '/usr/bin/Rscript';
$r_script_full_path = $r_script_path_dir . $script_name;

if (!file_exists($r_executable_path) || !is_executable($r_executable_path)) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => "Rscript executable not found or not executable at: {$r_executable_path}"]);
    exit();
}

if (!file_exists($r_script_full_path) || !is_readable($r_script_full_path)) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => "R script not found or not readable at: {$r_script_full_path}"]);
    exit();
}

// Build the command, specifying the R executable directly.
$params_json_str = json_encode($parameters, JSON_UNESCAPED_SLASHES);
if ($params_json_str === false) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => 'Failed to encode parameters to JSON.']);
    exit();
}

$command = escapeshellcmd($r_executable_path) . " " . escapeshellarg($r_script_full_path) . " " . escapeshellarg($temp_data_file) . " " . escapeshellarg($params_json_str);

// --- Use proc_open for better error capture ---
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin
   1 => array("pipe", "w"),  // stdout
   2 => array("pipe", "w")   // stderr
);

$process = proc_open($command, $descriptorspec, $pipes);

if (!is_resource($process)) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => 'Failed to open process to R.']);
    exit();
}

$stdout = stream_get_contents($pipes[1]);
fclose($pipes[1]);

$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);

$return_code = proc_close($process);

// Clean up the temporary data file
if (file_exists($temp_data_file)) {
    unlink($temp_data_file);
}

if ($return_code !== 0) {
    http_response_code(500);
    echo json_encode([
        'status' => 'error', 
        'message' => "R script execution failed. Exit code: {$return_code}", 
        'r_stdout' => $stdout, 
        'r_stderr' => $stderr
    ]);
    exit();
}

$r_results = json_decode($stdout, true);

if (json_last_error() !== JSON_ERROR_NONE) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => 'Failed to decode JSON from R script output.', 'r_stdout' => $stdout, 'r_stderr' => $stderr]);
    exit();
}

try {
    $dataSourceManager->logDataSourceUsage($data_source_id, (int)$person_id, 'Ran Analysis via API', (int)$user_id);
} catch (Exception $e) {
    error_log('Failed to log R analysis usage: ' . $e->getMessage());
}

echo json_encode(['status' => 'success', 'results' => $r_results]);
