/*
 *  @author Ranides Atterwim <ranides@gmail.com>
 *  @copyright Ranides Atterwim
 *  @license WTFPL
 *  @url http://ranides.net/projects/
 */
package net.ranides.assira.events;

import java.util.LinkedList;
import java.util.List;
import net.ranides.assira.collection.ArrayUtils;
import net.ranides.assira.collection.SetUtils;
import net.ranides.assira.collection.map.LazyMap;

import static org.junit.Assert.*;
import org.junit.Test;

/**
 *
 * @author ranides
 */
public class EventDispatcherTest {

    public EventDispatcherTest() {
    }

    private static class HitMap extends LazyMap<String, List<Integer>>  {
        private int counter = 0;

        @Override
        public List<Integer> apply(String source) {
            return new LinkedList<>();
        }

        public class HitListener<T extends Event> implements EventListener<T> {

            private final String name;

            public HitListener(String name) {
                this.name = name;
            }

            @Override
            public void handleEvent(T event) {
                get( name ).add(counter++);
            }
        }

    };


    @Test
    public void testPropagation() {
        HitMap hits = new HitMap();
        EventRouter main = new EventDispatcher();

        main.addEventListener(Event.class, hits.new HitListener<Event>("global") );
        main.addEventListener(IOEvent.class, hits.new HitListener<IOEvent>("io") );
        main.addEventListener(ReadEvent.class, hits.new HitListener<ReadEvent>("read") );
        main.addEventListener(WriteEvent.class, hits.new HitListener<WriteEvent>("write") );

        main.signalEvent(new WriteEvent());
        main.signalEvent(new ReadEvent());
        main.signalEvent(new Event(){});

        assertEquals(SetUtils.asHashSet("global", "io", "write", "read"), hits.keySet());

        assertEquals(ArrayUtils.asList(0,3,6), hits.get("global"));

        assertEquals(ArrayUtils.asList(1,4), hits.get("io"));

        assertEquals(ArrayUtils.asList(2), hits.get("write"));

        assertEquals(ArrayUtils.asList(5), hits.get("read"));

    }

    @SuppressWarnings("PMD")
    class IOEvent implements Event { }

    @SuppressWarnings("PMD")
    class ReadEvent extends IOEvent { }

    @SuppressWarnings("PMD")
    class WriteEvent extends IOEvent { }
}
