import java.io.PrintStream;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

/**
 * Un event loop de consola: espera una línea, busca el handler
 * registrado para su primera palabra y lo ejecuta. No sabe qué hace cada
 * comando.
 */
public class EventLoop {
    private final Map<String, CommandHandler> handlers = new LinkedHashMap<>();
    private final PrintStream out;
    private boolean running;

    public EventLoop(PrintStream out) {
        this.out = out;
    }

    /** Registrar un handler es suscribirse a un tipo de evento. */
    public void on(String command, CommandHandler handler) {
        handlers.put(command, handler);
    }

    public void stop() {
        running = false;
    }

    public void run(Scanner in) {
        running = true;
        while (running && in.hasNextLine()) {
            String line = in.nextLine().strip();
            if (line.isEmpty()) {
                continue;
            }
            List<String> words = Arrays.asList(line.split("\\s+"));
            CommandHandler handler = handlers.get(words.get(0));
            if (handler == null) {
                out.println("comando desconocido: " + words.get(0) + "; comandos: " + handlers.keySet());
                continue;
            }
            try {
                handler.handle(words.subList(1, words.size()));
            } catch (RuntimeException e) {
                out.println("error: " + e.getMessage());     // un handler que falla no detiene el ciclo
            }
        }
    }
}
