package net.onrc.onos.core.datastore.topology;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import java.util.HashMap;
import java.util.Map;

import net.onrc.onos.core.datastore.DataStoreClient;
import net.onrc.onos.core.datastore.IKVTable;
import net.onrc.onos.core.datastore.ObjectDoesntExistException;
import net.onrc.onos.core.datastore.ObjectExistsException;
import net.onrc.onos.core.datastore.WrongVersionException;
import net.onrc.onos.core.datastore.topology.KVSwitch.STATUS;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class KVSwitchTest {
    IKVTable switchTable;
    static final Long dpid1 = 0x1L;
    KVSwitch sw1;

    @Before
    public void setUp() throws Exception {
        switchTable = DataStoreClient.getClient().getTable(KVSwitch.GLOBAL_SWITCH_TABLE_NAME);
        sw1 = new KVSwitch(dpid1);
    }

    @After
    public void tearDown() throws Exception {
        DataStoreClient.getClient().dropTable(switchTable);
    }

    public KVSwitch assertSwitchInDataStore(final Long dpid, final STATUS status) {
        try {
            final KVSwitch sw = new KVSwitch(dpid);
            sw.read();
            assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw.getVersion());
            assertEquals(dpid, sw.getDpid());
            assertEquals(status, sw.getStatus());
            return sw;
        } catch (ObjectDoesntExistException e) {
            fail("Switch was not written to datastore");
        }
        return null;
    }

    public void assertSwitchNotInDataStore(final Long dpid) {
        final KVSwitch sw = new KVSwitch(dpid);
        try {
            sw.read();
            fail("Switch was not supposed to be there in datastore");
        } catch (ObjectDoesntExistException e) {
        }
    }

    @Test
    public void testGetAllSwitches() throws ObjectExistsException {
        final int NUM_SWITCHES = 100;
        Map<Long, KVSwitch> expected = new HashMap<>();
        for (long dpid = 1; dpid <= NUM_SWITCHES; ++dpid) {
            KVSwitch sw = new KVSwitch(dpid);
            sw.setStatus(STATUS.ACTIVE);
            sw.create();
            assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw.getVersion());
            expected.put(sw.getDpid(), sw);
        }

        Iterable<KVSwitch> switches = KVSwitch.getAllSwitches();

        for (KVSwitch sw : switches) {
            KVSwitch expectedSw = expected.get(sw.getDpid());
            assertNotNull(expectedSw);
            assertEquals(expectedSw.getDpid(), sw.getDpid());
            assertEquals(expectedSw.getStatus(), sw.getStatus());
            assertEquals(expectedSw.getVersion(), sw.getVersion());

            assertArrayEquals(expectedSw.getKey(), sw.getKey());
        }
    }

    @Test
    public void testCreate() throws ObjectExistsException {
        sw1.setStatus(STATUS.ACTIVE);
        sw1.create();
        assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw1.getVersion());

        assertEquals(dpid1, sw1.getDpid());
        assertEquals(STATUS.ACTIVE, sw1.getStatus());

        assertSwitchInDataStore(dpid1, STATUS.ACTIVE);
    }

    @Test(expected = ObjectExistsException.class)
    public void testCreateFailAlreadyExist() throws ObjectExistsException {
        // setup pre-existing Switch
        KVSwitch sw = new KVSwitch(dpid1);
        sw.forceCreate();
        assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw.getVersion());
        assertSwitchInDataStore(dpid1, STATUS.INACTIVE);

        sw1.setStatus(STATUS.ACTIVE);
        sw1.create();
        fail("Should have thrown an exception");
    }

    @Test
    public void testForceCreate() {
        // setup pre-existing Switch
        KVSwitch sw = new KVSwitch(dpid1);
        sw.forceCreate();
        assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw.getVersion());
        assertSwitchInDataStore(dpid1, STATUS.INACTIVE);


        sw1.setStatus(STATUS.ACTIVE);
        sw1.forceCreate();
        assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw1.getVersion());

        assertEquals(dpid1, sw1.getDpid());
        assertEquals(STATUS.ACTIVE, sw1.getStatus());
        assertSwitchInDataStore(dpid1, STATUS.ACTIVE);
    }

    @Test
    public void testRead() throws ObjectDoesntExistException {
        // setup pre-existing Switch
        KVSwitch sw = new KVSwitch(dpid1);
        sw.setStatus(STATUS.ACTIVE);
        sw.forceCreate();
        assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw.getVersion());
        assertSwitchInDataStore(dpid1, STATUS.ACTIVE);

        sw1.read();
        assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw1.getVersion());
        assertEquals(sw.getVersion(), sw1.getVersion());
        assertEquals(dpid1, sw1.getDpid());
        assertEquals(STATUS.ACTIVE, sw1.getStatus());
    }

    @Test(expected = ObjectDoesntExistException.class)
    public void testReadFailNoExist() throws ObjectDoesntExistException {

        sw1.read();
        fail("Should have thrown an exception");
    }

    @Test
    public void testUpdate() throws ObjectDoesntExistException, WrongVersionException {
        // setup pre-existing Switch
        KVSwitch sw = new KVSwitch(dpid1);
        sw.setStatus(STATUS.ACTIVE);
        sw.forceCreate();
        assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw.getVersion());
        assertSwitchInDataStore(dpid1, STATUS.ACTIVE);


        sw1.read();
        assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw1.getVersion());

        sw1.setStatus(STATUS.INACTIVE);
        sw1.update();
        assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw1.getVersion());
        assertNotEquals(sw.getVersion(), sw1.getVersion());
        assertEquals(dpid1, sw1.getDpid());
        assertEquals(STATUS.INACTIVE, sw1.getStatus());
    }

    @Test
    public void testDelete() throws ObjectDoesntExistException, WrongVersionException {
        // setup pre-existing Switch
        KVSwitch sw = new KVSwitch(dpid1);
        sw.setStatus(STATUS.ACTIVE);
        sw.forceCreate();
        assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw.getVersion());
        assertSwitchInDataStore(dpid1, STATUS.ACTIVE);


        try {
            sw1.read();
        } catch (ObjectDoesntExistException e) {
            fail("Failed reading switch to delete");
        }
        assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw1.getVersion());
        sw1.delete();
        assertSwitchNotInDataStore(dpid1);
    }

    @Test
    public void testForceDelete() {
        // setup pre-existing Switch
        KVSwitch sw = new KVSwitch(dpid1);
        sw.setStatus(STATUS.ACTIVE);
        sw.forceCreate();
        assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw.getVersion());
        assertSwitchInDataStore(dpid1, STATUS.ACTIVE);


        sw1.forceDelete();
        assertNotEquals(DataStoreClient.getClient().VERSION_NONEXISTENT(), sw1.getVersion());
    }

}
