/**
 *    Copyright 2011, Big Switch Networks, Inc.
 *    Originally created by David Erickson, Stanford University
 *
 *    Licensed under the Apache License, Version 2.0 (the "License"); you may
 *    not use this file except in compliance with the License. You may obtain
 *    a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 *    License for the specific language governing permissions and limitations
 *    under the License.
 **/

package net.floodlightcontroller.core.util;

import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import net.floodlightcontroller.core.IOFMessageListener;
import net.floodlightcontroller.test.FloodlightTestCase;

import org.junit.Test;
import org.projectfloodlight.openflow.protocol.OFType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MessageDispatcherTest extends FloodlightTestCase {
    private static final Logger log = LoggerFactory.getLogger(MessageDispatcherTest.class);

    IOFMessageListener createLMock(String name) {
        IOFMessageListener mock = createNiceMock(IOFMessageListener.class);
        expect(mock.getName()).andReturn(name).anyTimes();
        return mock;
    }

    void addPrereqs(IOFMessageListener mock, String... deps) {
        for (String dep : deps) {
            expect(mock.isCallbackOrderingPrereq(OFType.PACKET_IN, dep)).andReturn(true)
                    .anyTimes();
        }
    }

    void testOrdering(ArrayList<IOFMessageListener> inputListeners) {
        ListenerDispatcher<OFType, IOFMessageListener> ld =
                new ListenerDispatcher<OFType, IOFMessageListener>();

        for (IOFMessageListener l : inputListeners) {
            ld.addListener(OFType.PACKET_IN, l);
        }
        for (IOFMessageListener l : inputListeners) {
            verify(l);
        }

        List<IOFMessageListener> result = ld.getOrderedListeners();
        StringWriter sw = new StringWriter();
        PrintWriter out = new PrintWriter(sw);

        out.print("Ordering: ");
        for (IOFMessageListener l : result) {
            out.print(l.getName());
            out.print(",");
        }
        out.print("\n");
        log.debug(sw.toString());

        for (int ind_i = 0; ind_i < result.size(); ind_i++) {
            IOFMessageListener i = result.get(ind_i);
            for (int ind_j = ind_i + 1; ind_j < result.size(); ind_j++) {
                IOFMessageListener j = result.get(ind_j);

                boolean orderwrong =
                        (i.isCallbackOrderingPrereq(OFType.PACKET_IN, j.getName()) ||
                        j.isCallbackOrderingPostreq(OFType.PACKET_IN, i.getName()));
                assertFalse("Invalid order: " +
                        ind_i + " (" + i.getName() + ") " +
                        ind_j + " (" + j.getName() + ") ", orderwrong);
            }
        }
    }

    void randomTestOrdering(ArrayList<IOFMessageListener> mocks) {
        Random rand = new Random(0);
        ArrayList<IOFMessageListener> random =
                new ArrayList<IOFMessageListener>();
        random.addAll(mocks);
        for (int i = 0; i < 20; i++) {
            for (int j = 0; j < random.size(); j++) {
                int ind = rand.nextInt(mocks.size() - 1);
                IOFMessageListener tmp = random.get(j);
                random.set(j, random.get(ind));
                random.set(ind, tmp);
            }
            testOrdering(random);
        }
    }

    @Test
    public void testCallbackOrderingSimple() throws Exception {
        ArrayList<IOFMessageListener> mocks =
                new ArrayList<IOFMessageListener>();
        for (int i = 0; i < 10; i++) {
            mocks.add(createLMock("" + i));
        }
        for (int i = 1; i < 10; i++) {
            addPrereqs(mocks.get(i), "" + (i - 1));
        }
        for (IOFMessageListener l : mocks) {
            replay(l);
        }
        randomTestOrdering(mocks);
    }

    @Test
    public void testCallbackOrderingPartial() throws Exception {
        ArrayList<IOFMessageListener> mocks =
                new ArrayList<IOFMessageListener>();
        for (int i = 0; i < 10; i++) {
            mocks.add(createLMock("" + i));
        }
        for (int i = 1; i < 5; i++) {
            addPrereqs(mocks.get(i), "" + (i - 1));
        }
        for (int i = 6; i < 10; i++) {
            addPrereqs(mocks.get(i), "" + (i - 1));
        }
        for (IOFMessageListener l : mocks) {
            replay(l);
        }
        randomTestOrdering(mocks);
    }

    @Test
    public void testCallbackOrderingPartial2() throws Exception {
        ArrayList<IOFMessageListener> mocks =
                new ArrayList<IOFMessageListener>();
        for (int i = 0; i < 10; i++) {
            mocks.add(createLMock("" + i));
        }
        for (int i = 2; i < 5; i++) {
            addPrereqs(mocks.get(i), "" + (i - 1));
        }
        for (int i = 6; i < 9; i++) {
            addPrereqs(mocks.get(i), "" + (i - 1));
        }
        for (IOFMessageListener l : mocks) {
            replay(l);
        }
        randomTestOrdering(mocks);
    }
}
