package edu.upvehu.gbg.xml;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * Clase de ejemplo para leer y procesar un documento XML
 * utilizando la Simple API for XML (SAX) en Java.
 * Es un modelo basado en eventos, ideal para archivos grandes.
 */
public class LectorXMLSAX extends DefaultHandler {

    private StringBuilder currentValue = new StringBuilder();
    private boolean isInsideTexto = false;
    private String currentRemitente = "";
    private List<String> mensajesProcesados = new ArrayList<>();

    // Este método principal inicializa el parser y comienza el proceso
    public static void main(String[] args) {
        final String NOMBRE_ARCHIVO = "conversacion_manual.xml";
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            
            LectorXMLSAX handler = new LectorXMLSAX();
            System.out.println("--- Procesando " + NOMBRE_ARCHIVO + " con SAX ---");
            
            // El parser lee el archivo y notifica los eventos al handler
            parser.parse(new File(NOMBRE_ARCHIVO), handler);

            System.out.println("\n--- Resumen de Mensajes Extraídos (SAX) ---");
            for (String mensaje : handler.mensajesProcesados) {
                System.out.println(mensaje);
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // Se llama cuando el parser encuentra el inicio de un elemento
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // Reiniciar el buffer para el nuevo elemento
        currentValue.setLength(0);

        if (qName.equalsIgnoreCase("mensaje")) {
            // Capturamos el remitente para usarlo en la salida
            currentRemitente = attributes.getValue("remitente");
        } else if (qName.equalsIgnoreCase("texto")) {
            // Indicamos que estamos dentro de la etiqueta <texto>
            isInsideTexto = true;
        }
    }

    // Se llama cuando el parser encuentra contenido textual
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (isInsideTexto) {
            currentValue.append(ch, start, length);
        }
    }

    // Se llama cuando el parser encuentra el final de un elemento
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (qName.equalsIgnoreCase("texto")) {
            // Cuando termina <texto>, guardamos el contenido extraído
            String texto = currentValue.toString().trim();
            if (!texto.isEmpty()) {
                mensajesProcesados.add(String.format("De: %-20s | Texto: %s", currentRemitente, texto));
            }
            isInsideTexto = false;
        }
    }
}