HashtagMessage.java

package tweetoscope;

/**
 * =====================================================
 * CLASSE HashtagMessage - Structure de données pour les hashtags
 * =====================================================
 * 
 * Cette classe représente un hashtag extrait d'un tweet.
 * Elle contient les informations essentielles pour le traitement.
 * 
 * Utilisation :
 * - Utilisée dans le pipeline entre HashtagExtractor et HashtagCounter
 * - Sérialisée/désérialisée en JSON pour Kafka
 * - Permet de tracer l'origine de chaque hashtag
 * 
 * Format JSON (dans Kafka) :
 *   {"hashtag":"#bitcoin","timestamp":1700896200000,"tweetId":"123456"}
 * 
 * Champs :
 * - hashtag : le texte du hashtag (ex: "#bitcoin")
 * - timestamp : quand le tweet a été créé (en millisecondes depuis epoch)
 * - tweetId : ID du tweet d'origine (pour traçabilité)
 * 
 * Pattern :
 * - POJO (Plain Old Java Object) : simple classe avec getters/setters
 * - Sérializable en JSON avec Gson
 * - Immutable après création (bonnes pratiques)
 * 
 * @author 
 */
public class HashtagMessage {
    
    /**
     * VARIABLE MEMBRE : hashtag
     * 
     * Le texte du hashtag extrait du tweet.
     * 
     * Type : String
     * 
     * Format :
     * - Avec le "#" : "#bitcoin", "#covid", "#AI"
     * - Ou sans selon la configuration
     * 
     * Exemple :
     *   hashtag = "#bitcoin"
     *   - Utilisé comme clé Kafka (pour le partitioning)
     *   - Tous les tweets avec #bitcoin → même partition
     * 
     * Utilité :
     * - Partitioning par hashtag (tous les #bitcoin ensemble)
     * - Clé pour l'agrégation dans HashtagCounter
     * - Traçabilité
     */
    private String hashtag;
    
    /**
     * VARIABLE MEMBRE : timestamp
     * 
     * Quand le tweet contenant ce hashtag a été créé.
     * 
     * Type : long (millisecondes depuis epoch Unix - 1970-01-01)
     * 
     * Exemple :
     *   timestamp = 1700896200000
     *   → 2023-11-25 14:30:00 UTC
     * 
     * Utilité :
     * - Ordre chronologique des hashtags
     * - Fenêtres de temps dans Kafka Streams
     * - Analytics (quand le hashtag est devenu populaire)
     * 
     * Conversion :
     *   java.time.Instant.ofEpochMilli(timestamp)
     *   → convertit le long en Instant
     */
    private long timestamp;
    
    /**
     * VARIABLE MEMBRE : tweetId
     * 
     * ID unique du tweet d'origine.
     * 
     * Type : String
     * 
     * Utilité :
     * - Traçabilité complète du hashtag
     * - Si on trouve un hashtag intéressant, on peut retrouver le tweet
     * - Debugging et audits
     * - Éviter les doublons
     * 
     * Exemple :
     *   tweetId = "1234567890"
     *   - Référence vers le tweet original
     *   - Peut être utilisé pour chercher le tweet complet ailleurs
     */
    private String tweetId;

    /**
     * =====================================================
     * CONSTRUCTEUR 1 : Constructeur par défaut (sans paramètres)
     * =====================================================
     * 
     * Utilisé uniquement par Gson pour la désérialisation JSON.
     * 
     * Processus :
     * 1. Gson appelle ce constructeur (création vide)
     * 2. Gson utilise les setters pour remplir les champs
     * 3. Résultat : HashtagMessage rempli avec les données JSON
     * 
     * Exemple de désérialisation :
     *   JSON : {"hashtag":"#bitcoin","timestamp":1700896200000,"tweetId":"123"}
     *   ↓ Gson.fromJson()
     *   1. Crée HashtagMessage() vide
     *   2. appelle setHashtag("#bitcoin")
     *   3. appelle setTimestamp(1700896200000)
     *   4. appelle setTweetId("123")
     *   ↓
     *   HashtagMessage(hashtag=#bitcoin, timestamp=..., tweetId=123)
     */
    public HashtagMessage() {
        // Default constructor for Gson
    }

    /**
     * =====================================================
     * CONSTRUCTEUR 2 : Constructeur avec tous les paramètres
     * =====================================================
     * 
     * Utilisé pour créer un HashtagMessage programmatiquement
     * (depuis Java, pas depuis JSON).
     * 
     * Utilisation :
     * - Quand HashtagExtractor extrait un hashtag d'un tweet
     * - Pour construire l'objet avant sérialisation JSON
     * 
     * Exemple :
     *   Tweet tweet = ...;
     *   String hashtag = "#bitcoin";
     *   long timestamp = tweet.getCreatedAt().toInstant().toEpochMilli();
     *   HashtagMessage msg = new HashtagMessage(hashtag, timestamp, tweet.getId());
     *   
     *   // Puis sérialisation en JSON
     *   String json = gson.toJson(msg);
     *   // JSON : {"hashtag":"#bitcoin","timestamp":..., "tweetId":"..."}
     * 
     * @param hashtag Le texte du hashtag (ex: "#bitcoin")
     * @param timestamp Quand le tweet a été créé (millisecondes)
     * @param tweetId ID du tweet d'origine
     */
    public HashtagMessage(String hashtag, long timestamp, String tweetId) {
        this.hashtag = hashtag;
        this.timestamp = timestamp;
        this.tweetId = tweetId;
    }

    /**
     * =====================================================
     * GETTER : getHashtag()
     * =====================================================
     * 
     * Retourne le texte du hashtag.
     * 
     * @return Le hashtag (ex: "#bitcoin")
     */
    public String getHashtag() {
        return hashtag;
    }

    /**
     * =====================================================
     * SETTER : setHashtag()
     * =====================================================
     * 
     * Définit le texte du hashtag.
     * Utilisé par Gson lors de la désérialisation JSON.
     * 
     * @param hashtag Le hashtag à définir
     */
    public void setHashtag(String hashtag) {
        this.hashtag = hashtag;
    }

    /**
     * =====================================================
     * GETTER : getTimestamp()
     * =====================================================
     * 
     * Retourne quand le tweet a été créé.
     * 
     * @return Timestamp en millisecondes (epoch Unix)
     */
    public long getTimestamp() {
        return timestamp;
    }

    /**
     * =====================================================
     * SETTER : setTimestamp()
     * =====================================================
     * 
     * Définit le timestamp du tweet.
     * Utilisé par Gson lors de la désérialisation JSON.
     * 
     * @param timestamp Le timestamp (millisecondes)
     */
    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    /**
     * =====================================================
     * GETTER : getTweetId()
     * =====================================================
     * 
     * Retourne l'ID du tweet d'origine.
     * 
     * @return ID du tweet (ex: "1234567890")
     */
    public String getTweetId() {
        return tweetId;
    }

    /**
     * =====================================================
     * SETTER : setTweetId()
     * =====================================================
     * 
     * Définit l'ID du tweet d'origine.
     * Utilisé par Gson lors de la désérialisation JSON.
     * 
     * @param tweetId L'ID du tweet
     */
    public void setTweetId(String tweetId) {
        this.tweetId = tweetId;
    }

    /**
     * =====================================================
     * MÉTHODE toString() - Représentation en string
     * =====================================================
     * 
     * Retourne une représentation textuelle du HashtagMessage.
     * Utile pour les logs et le debugging.
     * 
     * Format :
     *   HashtagMessage{hashtag='#bitcoin', timestamp=1700896200000, tweetId='123456'}
     * 
     * Exemple d'utilisation :
     *   HashtagMessage msg = new HashtagMessage("#bitcoin", 1700896200000, "123");
     *   logger.info(msg.toString());
     *   // Log: HashtagMessage{hashtag='#bitcoin', timestamp=1700896200000, tweetId='123'}
     * 
     * @return String représentant l'objet avec tous ses champs
     */
    @Override
    public String toString() {
        return "HashtagMessage{" +
                "hashtag='" + hashtag + '\'' +
                ", timestamp=" + timestamp +
                ", tweetId='" + tweetId + '\'' +
                '}';
    }
}