package net.onrc.onos.core.registry;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.onrc.onos.core.registry.IControllerRegistryService.ControlChangeCallback;
import net.onrc.onos.core.util.IdBlock;
import net.onrc.onos.core.util.OnosInstanceId;

import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.projectfloodlight.openflow.util.HexString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Unit test for {@link StandaloneRegistry}.
 */
public class StandaloneRegistryTest {

    private static final Logger log = LoggerFactory.getLogger(StandaloneRegistryTest.class);

    protected static final long TIMEOUT_MSEC = 1000;

    protected StandaloneRegistry registry;

    /**
     * Implementation of {@link ControlChangeCallback} which defines callback interfaces called by Registry.
     * This class remembers past callback parameters and provides methods to access them.
     * This class also provides CountDownLatch so one can wait until the callback be called
     * specific times (specified by constructor parameter). Particularly, the first time callback
     * called is supposed for registration, this class has an independent latch to wait for
     * the first callback.
     */
    public static class LoggingCallback implements ControlChangeCallback {
        private LinkedList<Long> dpidsCalledback = new LinkedList<Long>();
        private LinkedList<Boolean> controlsCalledback = new LinkedList<Boolean>();
        private CountDownLatch lock = null, registerLock = null;


        /**
         * Constructor with number of times callback to be called.
         *
         * @param numberToCall Number of times expected callback to be called
         */
        public LoggingCallback(int numberToCall) {
            lock = new CountDownLatch(numberToCall);
            registerLock = new CountDownLatch(1);
        }

        /**
         * Wait until registration is finished (callback is called for the first time).
         *
         * @throws InterruptedException
         */
        public void waitForRegistration() throws InterruptedException {
            registerLock.await();
        }

        /**
         * Wait for registration specifying timeout.
         *
         * @param msec Milliseconds to timeout
         * @throws InterruptedException
         */
        public void waitForRegistration(long msec) throws InterruptedException {
            registerLock.await(msec, TimeUnit.MILLISECONDS);
        }

        /**
         * Wait until callback is called specific times.
         *
         * @throws InterruptedException
         */
        public void waitUntilCalled() throws InterruptedException {
            lock.await();
        }

        /**
         * Wait until callback is called specific times, specifying timeout.
         *
         * @param msec Milliseconds to timeout
         * @throws InterruptedException
         */
        public void waitUntilCalled(long msec) throws InterruptedException {
            lock.await(msec, TimeUnit.MILLISECONDS);
        }

        /**
         * Get DPID parameter given by specific callback time.
         *
         * @param index Specify which time to get parameter
         * @return DPID value by number.
         */
        public Long getDpid(int index) {
            return dpidsCalledback.get(index);
        }

        /**
         * Get hasControl parameter given by specific callback time.
         *
         * @param index Specify which time to get parameter
         * @return hasControl value
         */
        public Boolean getControl(int index) {
            return controlsCalledback.get(index);
        }

        /**
         * Get DPID parameter given by latest call.
         *
         * @return DPID value by number
         */
        public Long getLatestDpid() {
            return dpidsCalledback.peekLast();
        }

        /**
         * Get hasControl parameter given by latest call.
         *
         * @return hasControl value
         */
        public Boolean getLatestControl() {
            return controlsCalledback.peekLast();
        }

        @Override
        public void controlChanged(long dpid, boolean hasControl) {
            dpidsCalledback.addLast(dpid);
            controlsCalledback.addLast(hasControl);

            lock.countDown();
            registerLock.countDown();
        }
    }



    @Before
    public void setUp() throws Exception {
        FloodlightModuleContext fmc = new FloodlightModuleContext();
        registry = new StandaloneRegistry();
        registry.init(fmc);
    }

    @After
    public void tearDown() {
    }

    /**
     * Test if {@link StandaloneRegistry#registerController(String)} can run without error.
     */
    @Test
    public void testRegisterController() {
        String controllerIdToRegister = "test";
        try {
            registry.registerController(controllerIdToRegister);
        } catch (RegistryException e) {
            e.printStackTrace();
            fail(e.getMessage());
        }

        // Register Controller ID doubly
        try {
            registry.registerController(controllerIdToRegister);
            fail("Double registration goes through without exception");
        } catch (RegistryException e) {
            // expected behavior
            log.debug("Exception thrown as expected", e);
        }
    }

    /**
     * Test if {@link StandaloneRegistry#getOnosInstanceId()} can return
     * correct ID.
     *
     * @throws RegistryException
     */
    @Test
    public void testGetOnosInstanceId() throws RegistryException {
        String controllerIdToRegister = "test";

        // try before controller is registered
        OnosInstanceId onosInstanceId = registry.getOnosInstanceId();
        assertNull(onosInstanceId);

        // register
        registry.registerController(controllerIdToRegister);

        // call getOnosInstanceId and verify
        onosInstanceId = registry.getOnosInstanceId();
        assertNotNull(onosInstanceId);
        assertEquals(controllerIdToRegister, onosInstanceId.toString());
    }

    /**
     * Test if {@link StandaloneRegistry#getAllControllers()} can return correct list of controllers.
     *
     * @throws RegistryException
     */
    @Test
    public void testGetAllControllers() throws RegistryException {
        String controllerIdToRegister = "test";

        // Test before register controller
        try {
            Collection<String> ctrls = registry.getAllControllers();
            assertFalse(ctrls.contains(controllerIdToRegister));
        } catch (RegistryException e) {
            e.printStackTrace();
            fail(e.getMessage());
        }

        // register
        registry.registerController(controllerIdToRegister);

        // Test after register controller
        try {
            Collection<String> ctrls = registry.getAllControllers();
            assertTrue(ctrls.contains(controllerIdToRegister));
        } catch (RegistryException e) {
            e.printStackTrace();
            fail(e.getMessage());
        }
    }

    /**
     * Test if {@link StandaloneRegistry#requestControl(long, ControlChangeCallback)}
     * can correctly take control for switch so that callback is called.
     *
     * @throws RegistryException
     * @throws InterruptedException
     */
    @Test
    public void testRequestControl() throws InterruptedException, RegistryException {
        String controllerId = "test";
        registry.registerController(controllerId);

        LoggingCallback callback = new LoggingCallback(1);
        long dpidToRequest = 1000L;

        try {
            registry.requestControl(dpidToRequest, callback);
        } catch (RegistryException e) {
            e.printStackTrace();
            fail(e.getMessage());
        }

        callback.waitForRegistration();

        long dpidCallback = callback.getLatestDpid();
        boolean controlCallback = callback.getLatestControl();

        assertEquals(dpidToRequest, dpidCallback);
        assertTrue(controlCallback);
    }

    /**
     * Test if {@link StandaloneRegistry#releaseControl(long)}
     * can correctly release the control so that callback is called.
     *
     * @throws InterruptedException
     * @throws RegistryException
     */
    @Test
    public void testReleaseControl() throws InterruptedException, RegistryException {
        String controllerId = "test";
        registry.registerController(controllerId);

        long dpidToRequest = 1000L;
        LoggingCallback callback = new LoggingCallback(2);

        // to request and wait to take control
        registry.requestControl(dpidToRequest, callback);
        callback.waitForRegistration();

        registry.releaseControl(dpidToRequest);

        // verify
        callback.waitUntilCalled();
        assertEquals(dpidToRequest, (long) callback.getLatestDpid());
        assertFalse(callback.getLatestControl());
    }

    /**
     * Test if {@link StandaloneRegistry#hasControl(long)} returns correct status.
     *
     * @throws InterruptedException
     * @throws RegistryException
     */
    @Test
    public void testHasControl() throws InterruptedException, RegistryException {
        String controllerId = "test";
        registry.registerController(controllerId);

        long dpidToRequest = 1000L;
        LoggingCallback callback = new LoggingCallback(2);

        // Test before request control
        assertFalse(registry.hasControl(dpidToRequest));

        registry.requestControl(dpidToRequest, callback);
        callback.waitForRegistration();

        // Test after take control
        assertTrue(registry.hasControl(dpidToRequest));

        registry.releaseControl(dpidToRequest);

        callback.waitUntilCalled();

        // Test after release control
        assertFalse(registry.hasControl(dpidToRequest));
    }

    /**
     * Test if {@link StandaloneRegistry#getControllerForSwitch(long)} returns correct controller ID.
     *
     * @throws InterruptedException
     * @throws RegistryException
     */
    @Test
    public void testGetControllerForSwitch() throws InterruptedException, RegistryException {
        String controllerId = "test";
        registry.registerController(controllerId);

        long dpidToRequest = 1000L;
        LoggingCallback callback = new LoggingCallback(2);

        // Test before request control
        try {
            String controllerForSw = registry.getControllerForSwitch(dpidToRequest);
            assertNotEquals(controllerId, controllerForSw);
        } catch (RegistryException e) {
            fail("Failed before request control : " + e.getMessage());
            e.printStackTrace();
        }

        registry.requestControl(dpidToRequest, callback);
        callback.waitForRegistration();

        // Test after take control
        try {
            String controllerForSw = registry.getControllerForSwitch(dpidToRequest);
            assertEquals(controllerId, controllerForSw);
        } catch (RegistryException e) {
            fail("Failed after take control : " + e.getMessage());
            e.printStackTrace();
        }

        registry.releaseControl(dpidToRequest);
        callback.waitUntilCalled();

        // Test after release control
        try {
            String controllerForSw = registry.getControllerForSwitch(dpidToRequest);
            assertNotEquals(controllerId, controllerForSw);
        } catch (RegistryException e) {
            fail("Failed after release control : " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * Test if {@link StandaloneRegistry#getAllSwitches()} returns correct list of switches.
     *
     * @throws InterruptedException
     * @throws RegistryException
     */
    @Test
    public void testGetAllSwitches() throws InterruptedException, RegistryException {
        String controllerId = "test";
        registry.registerController(controllerId);

        long dpidToRequest = 1000L;
        String dpidToRequestStr = HexString.toHexString(dpidToRequest);
        LoggingCallback callback = new LoggingCallback(2);

        // Test before request control
        Map<String, List<ControllerRegistryEntry>> switches = registry.getAllSwitches();
        assertNotNull(switches);
        assertFalse(switches.keySet().contains(dpidToRequestStr));

        registry.requestControl(dpidToRequest, callback);
        callback.waitForRegistration();

        // Test after take control
        switches = registry.getAllSwitches();
        assertNotNull(switches);
        assertTrue(switches.keySet().contains(dpidToRequestStr));
        int count = 0;
        for (ControllerRegistryEntry ctrl : switches.get(dpidToRequestStr)) {
            if (ctrl.getControllerId().equals(controllerId)) {
                ++count;
            }
        }
        assertEquals(1, count);

        registry.releaseControl(dpidToRequest);
        callback.waitUntilCalled();

        // Test after release control
        switches = registry.getAllSwitches();
        assertNotNull(switches);
        assertFalse(switches.keySet().contains(dpidToRequestStr));
    }

    /**
     * Test if {@link StandaloneRegistry#getSwitchesControlledByController(String)} returns correct list of switches.
     *
     * @throws InterruptedException
     * @throws RegistryException
     */
    // TODO: remove @Ignore after implement StandaloneRegistry#getSwitchesControlledByController
    @Ignore
    @Test
    public void testGetSwitchesControlledByController() throws InterruptedException, RegistryException {
        String controllerId = "test";
        registry.registerController(controllerId);

        long dpidToRequest = 1000L;
        String dpidToRequestStr = HexString.toHexString(dpidToRequest);
        LoggingCallback callback = new LoggingCallback(2);

        // Test before request control
        Collection<Long> switches = registry.getSwitchesControlledByController(controllerId);
        assertNotNull(switches);
        assertFalse(switches.contains(dpidToRequestStr));

        registry.requestControl(dpidToRequest, callback);
        callback.waitForRegistration();

        // Test after take control
        switches = registry.getSwitchesControlledByController(controllerId);
        assertNotNull(switches);
        assertTrue(switches.contains(dpidToRequestStr));
        int count = 0;
        for (Long dpid : switches) {
            if (dpid == dpidToRequest) {
                ++count;
            }
        }
        assertEquals(1, count);

        registry.releaseControl(dpidToRequest);
        callback.waitUntilCalled();

        // Test after release control
        switches = registry.getSwitchesControlledByController(controllerId);
        assertNotNull(switches);
        assertFalse(switches.contains(dpidToRequestStr));
    }

    /**
     * Test if {@link StandaloneRegistry#allocateUniqueIdBlock()} returns appropriate object.
     * Get bulk of IdBlocks and check if they do have unique range of IDs.
     */
    @Test
    public void testAllocateUniqueIdBlock() {
        // Number of blocks to be verified that any of them has unique block
        final int numBlocks = 100;
        ArrayList<IdBlock> blocks = new ArrayList<IdBlock>(numBlocks);

        for (int i = 0; i < numBlocks; ++i) {
            blocks.add(registry.allocateUniqueIdBlock());
        }

        for (int i = 0; i < numBlocks; ++i) {
            IdBlock block1 = blocks.get(i);
            for (int j = i + 1; j < numBlocks; ++j) {
                IdBlock block2 = blocks.get(j);
                IdBlock lower, higher;

                if (block1.getStart() < block2.getStart()) {
                    lower = block1;
                    higher = block2;
                } else {
                    lower = block2;
                    higher = block1;
                }

                assertTrue(lower.getSize() > 0L);
                assertTrue(higher.getSize() > 0L);
                assertTrue(lower.getEnd() < higher.getStart());
            }
        }
    }
}
