<?php
/**
 * Fonctions pour l'intégration WordPress via l'API REST
 */

/**
 * Appelle l'API WordPress REST pour récupérer les articles
 *
 * @param string $endpoint Point de terminaison de l'API (ex: 'posts')
 * @param array $params Paramètres optionnels pour la requête
 * @return array Données retournées par l'API
 */
function callWordPressApi($endpoint, $params = []) {
    // Vérifier que WordPress est activé et configuré
    if (!defined('WORDPRESS_ENABLED') || !WORDPRESS_ENABLED || empty(WORDPRESS_URL)) {
        return [];
    }

    // Validation de l'URL WordPress pour prévenir SSRF
    if (!isValidWordPressUrl(WORDPRESS_URL)) {
        error_log('SECURITY: Invalid WordPress URL detected: ' . WORDPRESS_URL);
        return [];
    }

    // Construire l'URL de l'API
    $url = WORDPRESS_URL . '/wp-json/wp/v2/' . ltrim($endpoint, '/');

    // Ajouter les paramètres à l'URL
    if (!empty($params)) {
        $url .= '?' . http_build_query($params);
    }

    // Initialiser cURL avec options de sécurité
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
    curl_setopt($ch, CURLOPT_MAXREDIRS, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_USERAGENT, 'fediverse-oki-WordPress-Integration/1.0');

    // Exécuter la requête
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
    $error = curl_error($ch);
    curl_close($ch);

    // Traiter la réponse
    if ($response === false || !empty($error)) {
        error_log('WordPress API error: ' . $error);
        return [];
    }

    if ($httpCode < 200 || $httpCode >= 300) {
        error_log('WordPress API HTTP error: ' . $httpCode . ' for URL: ' . $url);
        return [];
    }

    // Validation du Content-Type
    if (!str_contains($contentType, 'application/json')) {
        error_log('WordPress API error: Invalid content type: ' . $contentType . ' for URL: ' . $url);
        return [];
    }

    // Décoder la réponse JSON
    $data = json_decode($response, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        error_log('WordPress API JSON decode error: ' . json_last_error_msg() . ' for URL: ' . $url);
        return [];
    }

    return $data ?: [];
}

/**
 * Valide l'URL WordPress pour prévenir les attaques SSRF
 *
 * @param string $url URL à valider
 * @return bool True si l'URL est valide et sûre
 */
function isValidWordPressUrl($url) {
    // Vérifier que l'URL est bien formée
    $parsed = parse_url($url);
    if (!$parsed || !isset($parsed['scheme']) || !isset($parsed['host'])) {
        return false;
    }

    // Autoriser uniquement HTTPS (ou HTTP en développement)
    if (!in_array($parsed['scheme'], ['https', 'http'])) {
        return false;
    }

    // Bloquer les adresses IP privées et locales
    $host = $parsed['host'];
    if (filter_var($host, FILTER_VALIDATE_IP)) {
        if (!filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
            return false;
        }
    }

    // Bloquer localhost et autres domaines dangereux
    $blockedHosts = ['localhost', '127.0.0.1', '::1', '0.0.0.0', 'metadata.google.internal'];
    if (in_array(strtolower($host), $blockedHosts)) {
        return false;
    }

    return true;
}

/**
 * Récupère les articles WordPress récents
 *
 * @param int $count Nombre d'articles à récupérer
 * @return array Liste des articles formatés
 */
function getWordPressPosts($count = null) {
    if ($count === null) {
        $count = defined('WORDPRESS_POSTS_COUNT') ? WORDPRESS_POSTS_COUNT : 6;
    }

    // Utiliser le cache pour les posts WordPress
    return callApiCached('wp-posts-' . $count, function() use ($count) {
        // Récupérer les posts via l'API WordPress REST
        $posts = callWordPressApi('posts', [
            'per_page' => $count,
            '_embed' => 'true' // Inclure les médias embarqués (featured image)
        ]);

        return formatWordPressPosts($posts);
    }, 900); // 15 minutes de cache
}

/**
 * Formate les données des articles WordPress
 *
 * @param array $posts Données brutes des articles
 * @return array Articles formatés
 */
function formatWordPressPosts($posts) {
    if (empty($posts)) {
        return [];
    }

    $formattedPosts = [];

    foreach ($posts as $post) {
        // Récupérer l'image mise en avant
        $featuredImage = '';
        if (isset($post['_embedded']['wp:featuredmedia'][0]['source_url'])) {
            $featuredImage = $post['_embedded']['wp:featuredmedia'][0]['source_url'];
        }

        // Nettoyer l'extrait HTML
        $excerpt = '';
        if (isset($post['excerpt']['rendered'])) {
            $excerpt = wp_strip_all_tags($post['excerpt']['rendered']);
            $excerpt = trim($excerpt);
            // Limiter à 150 caractères
            if (strlen($excerpt) > 150) {
                $excerpt = substr($excerpt, 0, 147) . '...';
            }
        }

        // Formater la date
        $date = '';
        if (isset($post['date'])) {
            $dateObj = new DateTime($post['date']);
            $date = $dateObj->format('d/m/Y');
        }

        $formattedPosts[] = [
            'id' => $post['id'],
            'title' => html_entity_decode($post['title']['rendered'], ENT_QUOTES, 'UTF-8'),
            'excerpt' => $excerpt,
            'featured_image' => $featuredImage,
            'link' => $post['link'],
            'date' => $date,
            'author' => isset($post['_embedded']['author'][0]['name']) ? $post['_embedded']['author'][0]['name'] : ''
        ];
    }

    return $formattedPosts;
}

/**
 * Fonction utilitaire pour nettoyer le HTML (similaire à wp_strip_all_tags de WordPress)
 *
 * @param string $string Chaîne à nettoyer
 * @return string Chaîne nettoyée
 */
function wp_strip_all_tags($string) {
    $string = preg_replace('@<(script|style)[^>]*?>.*?</\\1>@si', '', $string);
    $string = strip_tags($string);
    $string = preg_replace('/\s+/', ' ', $string);
    return trim($string);
}

?>
