package be.iminds.ilabt.jfed.log;

import javax.inject.Singleton;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Logger receives all results from servers and passes them on to interested listeners.
 * <p/>
 * This mechanism allows various classes to derive data from client actions, without initiating calls themselves.
 */
@Singleton
public class Logger {
    protected final List<ResultListener> resultListeners = new CopyOnWriteArrayList<>();

    /**
     * fireResult returns after all results have been processed
     */
    public synchronized void fireResult(ApiCallDetails reply) {
        for (ResultListener l : resultListeners)
            l.onResult(reply);
    }

    public synchronized void addResultListener(ResultListener l) {
        resultListeners.add(l);
    }

    public synchronized void removeResultListener(ResultListener l) {
        resultListeners.remove(l);
    }


    /**
     * returns a new logger object, that share the listeners of the original (even when updated),
     * and accepts new listeners that are not in the original object.
     */
    public Logger getWrappingLogger() {
        final Logger parentLogger = this;
        return new Logger() {
            @Override
            public synchronized void fireResult(ApiCallDetails reply) {
                for (ResultListener l : parentLogger.resultListeners)
                    l.onResult(reply);
                for (ResultListener l : resultListeners)
                    l.onResult(reply);
            }
        };
    }

    /**
     * @param l the listener to be added initially. may be null (no initial listener added in that case)
     */
    public Logger getWrappingLogger(ResultListener l) {
        Logger res = getWrappingLogger();
        if (l != null)
            res.addResultListener(l);
        return res;
    }
}
