/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package API;

import common.Instruction;
import common.Log;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;

/**
 *
 * @author Eugenio
 */
public class Middleware {

    // Todos os processors serão armazenados aqui, e cada evendo possui uma lista de processors separada por virgula
    protected static LinkedHashMap<String, API.MiddlewareInterface> processors = new LinkedHashMap<>();
    protected static HashMap<String, HashMap<String, ArrayList<String>>> events = new HashMap<>();

    public static void _init() {

    }

    public static void On(String selectors, String event, String processors) {
        HashMap<String, ArrayList<String>> s;
        ArrayList<String> processorsList = ProcToList(processors);
        for (String selector : selectors.split(",")) {
            if (!events.containsKey(selector)) {
                events.put(selector, new HashMap<>());
            }
            s = events.get(selector);

            if (!s.containsKey(event)) {
                s.put(event, new ArrayList<>());
            }

            s.get(event).addAll(processorsList);
        }
    }

    public static void Trigger(common.Code c, String selector, String event) throws Exception {
//        System.out.println("Try trigger:" + selector);
        if (events.containsKey(selector)) {
            HashMap<String, ArrayList<String>> t = events.get(selector);
            if (t.containsKey(event)) {
                ProcessorExecute(c, t.get(event));
            }
        }

    }

    public static void Add(String id, API.MiddlewareInterface p) throws Exception {
        if (processors.containsKey(id)) {
            Log.PrintWarning(
                    "Code Processor",
                    new Instruction().Set("msg", String.format("Tentativa de sobrescrita do processor %s.", id))
            );
        }
        processors.put(id, p);
    }

    protected static ArrayList<String> ProcToList(String events) {
//        System.out.println("events:" + events);
        ArrayList<String> r = new ArrayList<>();
        for (String p : events.replaceAll("\\s+", "").split(",")) {
            r.add(p);
        }
        return r;
    }

    public static void ProcessorExecute(common.Code c, ArrayList<String> eventList) throws Exception {
        for (String x : eventList) {

            if (x.equals("")) {
                continue;
            }

            if (!processors.containsKey(x)) {
                throw new Exception(String.format("Processador de código '%s' não definido!", x));
            }

            processors.get(x.trim()).Exec(c, processors);
        }
    }

}
