<?php
/**
 * filename	: mcp_proxy.php
 * location	: hub.collabit.at/
 * contents	: Proxies authenticated MCP requests using JWT Issuer for routing.
 */

require_once('conf.php');
require_once('proxy_routing_table.php');

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

if ('hub.collabit.at' !== ($_SERVER['HTTP_HOST'] ?? "")) {
	http_response_code(400);
	exit(json_encode(['error' => 'Invalid host'])); 
}

function getRequestHeader(string $name): ?string {
	$server_key = 'HTTP_' . strtoupper(str_replace('-', '_', $name));
	$server_value = $_SERVER[$server_key] ?? null;

	if (is_string($server_value) && trim($server_value) !== '') {
		return trim($server_value);
	}

	$direct_value = $_SERVER[$name] ?? null;
	if (is_string($direct_value) && trim($direct_value) !== '') {
		return trim($direct_value);
	}

	if ($name === 'Authorization') {
		$redirect_value = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ?? null;
		if (is_string($redirect_value) && trim($redirect_value) !== '') {
			return trim($redirect_value);
		}
	}

	if (function_exists('apache_request_headers')) {
		foreach (apache_request_headers() as $header_name => $header_value) {
			if (strcasecmp($header_name, $name) === 0 && trim((string)$header_value) !== '') {
				return trim((string)$header_value);
			}
		}
	}

	return null;
}

function getAuthorizationHeader(): ?string {
	return getRequestHeader('Authorization');
}

/**
 * Specifically extracts the Bearer token
 */
function getBearerToken() {
	$headers = getAuthorizationHeader();
	if (!empty($headers)) {
		if (preg_match('/Bearer\s(\S+)/i', $headers, $matches)) {
			return $matches[1];
		}
	}
	return null;
}

function getJWTIssuer() {
	$bearer = getBearerToken();
	if (!$bearer || !ctype_xdigit($bearer)) return null;

	$jwt = hex2bin($bearer);
	if ($jwt === false) return null;

	$parts = explode('.', $jwt);
	if (count($parts) !== 3) return null;
	$payload = json_decode(base64_decode(strtr($parts[1], '-_', '+/')), true);
	return $payload['iss'] ?? null;
}

// 2. Identify Tenant via JWT
$tenantBaseUrl = null;

$routing_table = routing::get_routing_table() ?? [];
if (empty($routing_table) || !is_array($routing_table)) {
	http_response_code(503);
	exit(json_encode(['error' => 'Routing not available']));
}

$issuer = getJWTIssuer();
$valid_issuers = array_column($routing_table, 'url');
if ($issuer && in_array($issuer, $valid_issuers)) {
	$tenantBaseUrl = $issuer;
}

if (!$tenantBaseUrl) {
	http_response_code(401);
	exit(json_encode(['error' => 'Tenant identification via JWT failed']));
}

// 3. Proxy Execution
$queryString = $_SERVER['QUERY_STRING'] ?? '';
$fullUrl = $tenantBaseUrl . "/mcp.php" . ($queryString ? '?' . $queryString : '');
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';

$ch = curl_init($fullUrl);
$headers = [
	'X-Forwarded-For: ' . ($_SERVER['REMOTE_ADDR'] ?? ''),
	'X-Forwarded-Proto: ' . ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http'),
	'X-Forwarded-Host: ' . ($_SERVER['HTTP_HOST'] ?? 'hub.collabit.at'),
	'X-Forwarded-Uri: ' . ($_SERVER['REQUEST_URI'] ?? '/mcp_proxy.php'),
];

foreach (['Authorization', 'Content-Type', 'Accept', 'X-Collabit-Key'] as $h) {
	$value = getRequestHeader($h);
	if ($value !== null) {
		$headers[] = "$h: $value";
	}
}

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

if ($method === 'POST') {
	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents('php://input'));
}

if ($method === 'GET' && ($_GET['subject'] ?? '') !== 'health') {
	// SSE Mode for MCP Streams
	header('Content-Type: text/event-stream');
	header('Cache-Control: no-cache');
	header('X-Accel-Buffering: no'); 
	curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data) {
		echo $data;
		if (ob_get_level() > 0) ob_flush();
		flush();
		return strlen($data);
	});
	curl_exec($ch);
} else {
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	$response = curl_exec($ch);
	$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	http_response_code($httpCode ?: 200);
	header('Access-Control-Allow-Origin: https://chatgpt.com');
	header('Content-Type: application/json');
	echo $response;
}
curl_close($ch);
