RecentTweetFilter.java

package tweetoscope.tweetsFilter;

import com.twitter.clientlib.model.Tweet;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;

/**
 * =====================================================
 * CLASSE RecentTweetFilter - Filtre par date
 * =====================================================
 * 
 * Ce filtre accepte UNIQUEMENT les tweets créés à partir d'une certaine date.
 * 
 * Objectif :
 * Filtrer les tweets anciens et ne garder que les plus récents.
 * 
 * Exemple d'utilisation :
 * - RecentTweetFilter(2023) accepte tous les tweets créés à partir du 1er janvier 2023 00:00:00 UTC
 * - RecentTweetFilter(OffsetDateTime.now().minusYears(1)) accepte les tweets du dernier an
 * 
 * Logique du filtre :
 * - Chaque tweet a une date de création (createdAt)
 * - Le filtre compare cette date avec un seuil (sinceDate)
 * - Si createdAt >= sinceDate → tweet accepté ✓
 * - Si createdAt < sinceDate → tweet rejeté ✗
 */
public class RecentTweetFilter implements TweetFilter.FilterCondition {

    // Logger pour tracer l'exécution et les événements
    private static final java.util.logging.Logger logger = java.util.logging.Logger.getLogger(RecentTweetFilter.class.getName());

    /**
     * VARIABLE MEMBRE : sinceDate
     * 
     * Cette variable stocke la DATE SEUIL du filtre.
     * - Tous les tweets créés À OU APRÈS cette date sont acceptés
     * - Tous les tweets créés AVANT cette date sont rejetés
     * 
     * Type OffsetDateTime :
     * - Représente une date + heure + fuseau horaire
     * - Exemple : 2023-01-01T00:00:00+00:00 (1er janvier 2023 à minuit UTC)
     * 
     * Exemple :
     *   sinceDate = 2023-01-01T00:00:00Z
     *   tweet créé le 2023-06-15 → accepté (après le seuil)
     *   tweet créé le 2022-12-31 → rejeté (avant le seuil)
     */
    private final OffsetDateTime sinceDate;

    /**
     * =====================================================
     * CONSTRUCTEUR 1 : Filtre basé sur une année
     * =====================================================
     * 
     * Crée un filtre qui accepte les tweets à partir d'une année spécifiée.
     * 
     * Fonctionnement :
     * - Convertit l'année en date complète : (année, 1er janvier, minuit, fuseau UTC)
     * - Stocke cette date dans sinceDate
     * 
     * Exemple :
     *   RecentTweetFilter(2023)
     *   → sinceDate = 2023-01-01T00:00:00Z
     *   → Accepte TOUS les tweets depuis le 1er janvier 2023 00:00:00 UTC
     * 
     * @param year L'année seuil (ex: 2022, 2023, 2024)
     *             Les tweets de cette année et après sont acceptés
     */
    public RecentTweetFilter(int year) {
        // Crée une date : 1er janvier de l'année donnée à minuit UTC
        // OffsetDateTime.of(année, mois, jour, heure, minute, seconde, nanoseconde, fuseau)
        this.sinceDate = OffsetDateTime.of(year, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
        
        // Log d'initialisation pour tracer l'action
        logger.info(() -> "RecentTweetFilter initialized; accepting tweets from year: " + year);
    }

    /**
     * =====================================================
     * CONSTRUCTEUR 2 : Filtre basé sur une date précise
     * =====================================================
     * 
     * Crée un filtre avec une date seuil exact (plus flexible que le constructeur 1).
     * 
     * Avantages par rapport au constructeur 1 :
     * - Permet de spécifier une date exacte (pas juste l'année)
     * - Permet de choisir le mois, le jour, l'heure, etc.
     * - Offre plus de granularité
     * 
     * Exemple :
     *   RecentTweetFilter(OffsetDateTime.parse("2023-06-15T14:30:00+02:00"))
     *   → Accepte les tweets depuis le 15 juin 2023 à 14h30 (fuseau +02:00)
     * 
     * @param sinceDate La date seuil exacte (ex: 2023-06-15T14:30:00Z)
     *                   Les tweets à ou après cette date sont acceptés
     */
    public RecentTweetFilter(OffsetDateTime sinceDate) {
        // Stocke la date seuil fournie
        this.sinceDate = sinceDate;
        
        // Log d'initialisation
        logger.info(() -> "RecentTweetFilter initialized; accepting tweets after: " + sinceDate);
    }

    /**
     * =====================================================
     * MÉTHODE match() - Teste si un tweet passe le filtre
     * =====================================================
     * 
     * Implémentation de l'interface FilterCondition.
     * Décide si un tweet doit être accepté ou rejeté.
     * 
     * Logique :
     * 1. Vérifie que le tweet a une date de création
     *    - Si NULL → tweet incomplet → REJETÉ
     * 2. Compare la date du tweet avec le seuil
     *    - Si createdAt >= sinceDate → ACCEPTÉ
     *    - Si createdAt < sinceDate → REJETÉ
     * 
     * Méthode isBefore() de OffsetDateTime :
     * - !x.isBefore(y) signifie : "x est à partir de y" ou "x >= y"
     * - C'est l'inverse logique : if(NOT before) = if(after or equal)
     * 
     * Exemples :
     *   sinceDate = 2023-01-01
     *   tweet1.createdAt = 2023-06-15 → !isBefore() = true → ACCEPTÉ ✓
     *   tweet2.createdAt = 2022-12-31 → !isBefore() = false → REJETÉ ✗
     *   tweet3.createdAt = null → return false → REJETÉ ✗
     * 
     * @param tweet Le tweet à tester
     * @return true si le tweet passe le filtre (date >= seuil), false sinon
     */
    @Override
    public boolean match(Tweet tweet) {
        // Vérification de sécurité : si la date de création est NULL
        // (tweet sans date = données incomplètes)
        if (tweet.getCreatedAt() == null) {
            return false;  // Rejette le tweet
        }
        
        // Teste si la date du tweet est à partir du seuil
        // !isBefore(sinceDate) = "la date du tweet est >= sinceDate"
        return !tweet.getCreatedAt().isBefore(sinceDate);
    }
}