<?php
/**
 * Journal des robots IA (dashboard Espierre, 13/10/2026). Hostinger ne donne pas les journaux d'accès :
 * on note nous-mêmes chaque passage d'un robot IA, une ligne par requête, dans ~/botlogs/{site}/{jour}.tsv
 * (hors du site). Le dashboard (tâche ai-bots-day) lit ces fichiers chaque jour et vérifie les IP publiées.
 * Colonnes : date ISO UTC, IP, robot, méthode, chemin, code HTTP.
 */
function espierre_botlog_robot($ua) {
    // Ordre : les plus précis d'abord
    $robots = array('OAI-SearchBot', 'ChatGPT-User', 'GPTBot', 'Perplexity-User', 'PerplexityBot',
        'Claude-User', 'Claude-SearchBot', 'ClaudeBot', 'anthropic-ai', 'MistralAI-User', 'DuckAssistBot',
        'Gemini-Deep-Research', 'Google-CloudVertexBot', 'meta-externalfetcher', 'meta-externalagent',
        'Applebot', 'Amazonbot', 'Bytespider', 'CCBot', 'YouBot', 'cohere-ai');
    foreach ($robots as $r) {
        if (stripos($ua, $r) !== false) return $r;
    }
    return null;
}

function espierre_botlog_ecrire($robot, $chemin, $code) {
    $racine = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : '';
    if ($racine === '') return;
    $site = preg_replace('/^www\./', '', strtolower(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'inconnu'));
    $site = preg_replace('/[^a-z0-9.-]/', '', $site);
    $dossier = dirname($racine, 3) . '/botlogs/' . $site;
    if (!is_dir($dossier)) @mkdir($dossier, 0750, true);
    $ligne = implode("\t", array(
        gmdate('Y-m-d\TH:i:s\Z'),
        isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '',
        $robot,
        isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : '',
        str_replace(array("\t", "\n", "\r"), ' ', substr($chemin, 0, 500)),
        (string) $code,
    )) . "\n";
    @file_put_contents($dossier . '/' . gmdate('Y-m-d') . '.tsv', $ligne, FILE_APPEND | LOCK_EX);
}

/*
 * Serveur de fichiers statiques pour les robots IA : appelé par la réécriture du .htaccess (bloc
 * ESPIERRE ROBOTS IA) à la place du fichier demandé ; note le passage puis sert le fichier tel quel.
 */
$racine = realpath($_SERVER['DOCUMENT_ROOT']);
$chemin = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';
$p = rawurldecode(strtok($chemin, '?'));
$robot = espierre_botlog_robot(isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '') ?: 'inconnu';

$types = array('html' => 'text/html; charset=utf-8', 'txt' => 'text/plain; charset=utf-8', 'xml' => 'application/xml; charset=utf-8',
    'json' => 'application/json; charset=utf-8', 'md' => 'text/markdown; charset=utf-8');
$fichier = null;
if (strpos($p, '..') === false && strpos($p, "\0") === false) {
    $cible = $racine . $p;
    if (is_dir($cible)) $cible = rtrim($cible, '/') . '/index.html';
    $reel = realpath($cible);
    $ext = $reel ? strtolower(pathinfo($reel, PATHINFO_EXTENSION)) : '';
    if ($reel && strpos($reel, $racine . '/') === 0 && is_file($reel) && isset($types[$ext])) $fichier = $reel;
}
// Dossier demandé sans barre finale : même redirection que le serveur
if ($fichier && is_dir($racine . $p) && substr($p, -1) !== '/') {
    espierre_botlog_ecrire($robot, $chemin, 301);
    header('Location: ' . $p . '/' . (strpos($chemin, '?') !== false ? substr($chemin, strpos($chemin, '?')) : ''), true, 301);
    exit;
}
$code = 200;
if (!$fichier) {
    $code = 404;
    $fichier = is_file($racine . '/404.html') ? $racine . '/404.html' : null;
}
espierre_botlog_ecrire($robot, $chemin, $code);
http_response_code($code);
if ($fichier) {
    header('Content-Type: ' . $types[strtolower(pathinfo($fichier, PATHINFO_EXTENSION))]);
    header('Cache-Control: public, max-age=0, must-revalidate');
    header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($fichier)) . ' GMT');
    if ($_SERVER['REQUEST_METHOD'] !== 'HEAD') readfile($fichier);
}
