<?php
/**
 * Video streaming API for Main VPS
 * Place this file in the web root of each main VPS as /api/stream.php
 */

// Include shared configuration
require_once __DIR__ . '/config.php';

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Range');

// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    exit(0);
}

// Adaptive streaming configuration - predefined chunk sizes to prevent abuse
$ALLOWED_CHUNK_SIZES = [
    'slow'   => 256 * 1024,      // 256KB for slow connections
    'medium' => 512 * 1024,      // 512KB for medium connections (default)
    'fast'   => 1024 * 1024,     // 1MB for fast connections
    'ultra'  => 2 * 1024 * 1024  // 2MB for ultra-fast connections
];

$DEFAULT_CHUNK_SIZE = 'medium';

/**
 * Get and validate chunk size from request
 */
function getValidatedChunkSize() {
    global $ALLOWED_CHUNK_SIZES, $DEFAULT_CHUNK_SIZE;
    
    $chunkType = $_GET['chunk'] ?? $DEFAULT_CHUNK_SIZE;
    
    // Validate chunk type is in allowed list
    if (!isset($ALLOWED_CHUNK_SIZES[$chunkType])) {
        $chunkType = $DEFAULT_CHUNK_SIZE;
    }
    
    return $ALLOWED_CHUNK_SIZES[$chunkType];
}

/**
 * Stream video file with range support
 */
function streamVideo($filepath, $chunkSize) {
    if (!file_exists($filepath)) {
        http_response_code(404);
        echo json_encode(['error' => 'File not found']);
        return;
    }
    
    $filesize = filesize($filepath);
    $start = 0;
    $end = $filesize - 1;
    
    // Handle range requests
    if (isset($_SERVER['HTTP_RANGE'])) {
        $range = $_SERVER['HTTP_RANGE'];
        if (preg_match('/bytes=(\d+)-(\d*)/', $range, $matches)) {
            $start = intval($matches[1]);
            if (!empty($matches[2])) {
                $end = intval($matches[2]);
            }
        }
        
        // Validate range
        if ($start > $end || $start >= $filesize || $end >= $filesize) {
            http_response_code(416);
            header("Content-Range: bytes */$filesize");
            return;
        }
        
        http_response_code(206);
        header("Content-Range: bytes $start-$end/$filesize");
    }
    
    $length = $end - $start + 1;
    
    // Set appropriate headers
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mimeType = finfo_file($finfo, $filepath);
    finfo_close($finfo);
    
    if (!$mimeType) {
        $mimeType = 'video/mp4'; // Default
    }
    
    header("Content-Type: $mimeType");
    header("Content-Length: $length");
    header("Accept-Ranges: bytes");
    header("Cache-Control: public, max-age=3600");
    header("Content-Disposition: inline");
    
    // Open file and seek to start position
    $file = fopen($filepath, 'rb');
    if (!$file) {
        http_response_code(500);
        echo json_encode(['error' => 'Cannot open file']);
        return;
    }
    
    fseek($file, $start);
    
    // Stream the file in chunks
    $bytesRemaining = $length;
    while (!feof($file) && $bytesRemaining > 0 && connection_status() === 0) {
        $readSize = min($chunkSize, $bytesRemaining);
        $data = fread($file, $readSize);
        echo $data;
        flush();
        $bytesRemaining -= strlen($data);
    }
    
    fclose($file);
}

// Main execution
try {
    $action = $_GET['action'] ?? '';
    $file = $_GET['file'] ?? '';
    
    if ($action !== 'stream') {
        throw new Exception('Invalid action');
    }
    
    if (empty($file)) {
        throw new Exception('File parameter is required');
    }
    
    if (!validatePath($file)) {
        throw new Exception('Invalid file path or security violation');
    }
    
    $fullPath = $BASE_PATH . $file;
    
    // Get validated chunk size from request
    $chunkSize = getValidatedChunkSize();
    
    streamVideo($fullPath, $chunkSize);
    
} catch (Exception $e) {
    http_response_code(400);
    header('Content-Type: application/json');
    echo json_encode([
        'error' => $e->getMessage(),
        'success' => false
    ]);
}
?>