/**
 * 
 */
package net.onrc.onos.util;

import static org.junit.Assert.*;

import java.util.*;

import junit.framework.TestCase;

import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
import net.onrc.onos.ofcontroller.util.FlowEntryId;
import net.onrc.onos.ofcontroller.util.FlowId;
import net.floodlightcontroller.core.internal.TestDatabaseManager;

import org.easymock.EasyMock;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import com.thinkaurelius.titan.core.TitanFactory;
import com.thinkaurelius.titan.core.TitanGraph;
import com.tinkerpop.blueprints.Vertex;

/**
 * @author Toshio Koide
 *
 */

@RunWith(PowerMockRunner.class)
@PrepareForTest({TitanFactory.class})
public class GraphDBOperationTest extends TestCase {
	private static TitanGraph testdb;
	private static GraphDBConnection conn;
	private static GraphDBOperation op;

	/**
	 * @throws java.lang.Exception
	 */
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}

	/**
	 * @throws java.lang.Exception
	 */
	@AfterClass
	public static void tearDownAfterClass() throws Exception {
	}

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		TestDatabaseManager.deleteTestDatabase();
		testdb = TestDatabaseManager.getTestDatabase();
//		TestDatabaseManager.populateTestData(titanGraph);

		String dummyPath = "/dummy/to/conf";
		// replace return value of TitanFactory.open() to dummy DB created above
		PowerMock.mockStatic(TitanFactory.class);
		EasyMock.expect(TitanFactory.open(dummyPath)).andReturn(testdb);
		PowerMock.replay(TitanFactory.class);
		
		conn = GraphDBConnection.getInstance(dummyPath);
		op = new GraphDBOperation(conn);
	}

	/**
	 * @throws java.lang.Exception
	 */
	@After
	public void tearDown() throws Exception {
		conn.close();
		testdb.shutdown();
		PowerMock.verifyAll();
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#newSwitch(net.onrc.onos.util.GraphDBConnection)}.
	 */
	@Test
	public final void testNewSwitch() {
		assertNull(op.searchSwitch("123"));

		op.newSwitch("123");		
		op.commit();

		ISwitchObject sw = op.searchSwitch("123");
		assertNotNull(op);
		assertEquals("123", sw.getDPID());
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchSwitch(net.onrc.onos.util.GraphDBConnection, java.lang.String)}.
	 */
	@Test
	public final void testSearchSwitch() {
		op.newSwitch("123");
		op.newSwitch("456");
		op.commit();

		ISwitchObject sw = op.searchSwitch("123");
		assertNotNull(sw);
		assertEquals("123", sw.getDPID());

		sw = op.searchSwitch("789");
		assertNull(sw);
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchActiveSwitch(net.onrc.onos.util.GraphDBConnection, java.lang.String)}.
	 */
	@Test
	public final void testSearchActiveSwitch() {
		op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
		op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
		op.commit();
		
		ISwitchObject sw = op.searchActiveSwitch("111");
		assertNotNull(sw);
		assertEquals("111", sw.getDPID());
		
		sw = op.searchActiveSwitch("222");
		assertNull(sw);	
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getActiveSwitches(net.onrc.onos.util.GraphDBConnection)}.
	 */
	@Test
	public final void testGetActiveSwitches() {
		op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
		op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
		op.commit();
		
		Iterator<ISwitchObject> i = op.getActiveSwitches().iterator();
		
		assertTrue(i.hasNext());
		assertEquals("111", i.next().getDPID());
		assertFalse(i.hasNext());
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getAllSwitches(net.onrc.onos.util.GraphDBConnection)}.
	 */
	@Test
	public final void testGetAllSwitches() {
		List<String> dpids = Arrays.asList("111", "222", "333");
		Collections.sort(dpids);
		
		for (String dpid: dpids) op.newSwitch(dpid);
		op.commit();

		List<String> actual_ids = new ArrayList<String>();
		for (ISwitchObject switchObj: op.getAllSwitches()) actual_ids.add(switchObj.getDPID());
		Collections.sort(actual_ids);

		assertArrayEquals(dpids.toArray(), actual_ids.toArray());
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getInactiveSwitches(net.onrc.onos.util.GraphDBConnection)}.
	 */
	@Test
	public final void testGetInactiveSwitches() {
		op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
		op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
		op.commit();
		
		Iterator<ISwitchObject> i = op.getInactiveSwitches().iterator();
		
		assertTrue(i.hasNext());
		assertEquals("222", i.next().getDPID());
		assertFalse(i.hasNext());
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getAllSwitchNotUpdatedFlowEntries(net.onrc.onos.util.GraphDBConnection)}.
	 */
	@Test
	public final void testGetAllSwitchNotUpdatedFlowEntries() {
		FlowEntryId flowEntryId10 = new FlowEntryId(10);
		FlowEntryId flowEntryId20 = new FlowEntryId(20);
		IFlowEntry flowEntry10 = op.newFlowEntry();
		IFlowEntry flowEntry20 = op.newFlowEntry();
		flowEntry10.setFlowEntryId(flowEntryId10.toString());
		flowEntry20.setFlowEntryId(flowEntryId20.toString());
		flowEntry10.setSwitchState("FE_SWITCH_NOT_UPDATED");
		flowEntry20.setSwitchState("FE_SWITCH_UPDATED");
 		op.commit();
		
		Iterator<IFlowEntry> flowEntries = op.getAllSwitchNotUpdatedFlowEntries().iterator();
		assertNotNull(flowEntries);
		assertTrue(flowEntries.hasNext());
		assertEquals(flowEntryId10.toString(), flowEntries.next().getFlowEntryId());
		assertFalse(flowEntries.hasNext());
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#removeSwitch(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject)}.
	 */
	@Test
	public final void testRemoveSwitch() {
		ISwitchObject sw = op.newSwitch("123");
		op.commit();	
		sw = op.searchSwitch("123");
		assertNotNull(sw);

		op.removeSwitch(sw);
		op.commit();
		
		assertNull(op.searchSwitch("123"));
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#newPort(net.onrc.onos.util.GraphDBConnection)}.
	 */
	@Test
	public final void testNewPort() {
		assertFalse(testdb.getVertices("type", "port").iterator().hasNext());
		
		IPortObject port = op.newPort((short) 10);
		assertTrue(port.getNumber() == 10);
		op.commit();
		
		Iterator<Vertex> vertices = testdb.getVertices("type", "port").iterator();
		assertTrue(vertices.hasNext());
		assertEquals(vertices.next().getProperty("number").toString(), "10");		
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchPort(net.onrc.onos.util.GraphDBConnection, java.lang.String, short)}.
	 */
	@Test
	public final void testSearchPort() {
		ISwitchObject sw;
		IPortObject port;
		
		sw = op.newSwitch("1");
		sw.addPort(op.newPort((short) 1));
		sw.addPort(op.newPort((short) 2));
		
		sw = op.newSwitch("2");
		sw.addPort(op.newPort((short) 1));
		sw.addPort(op.newPort((short) 2));

		op.commit();

		assertNull(op.searchPort("3", (short) 1));
		assertNull(op.searchPort("1", (short) 3));

		port = op.searchPort("1", (short) 1);
		assertNotNull(port);
		assertTrue(port.getNumber() == 1);
		sw = port.getSwitch();
		assertNotNull(sw);
		assertEquals("1", sw.getDPID());

		port = op.searchPort("1", (short) 2);
		assertNotNull(port);
		assertTrue(port.getNumber() == 2);
		sw = port.getSwitch();
		assertNotNull(sw);
		assertEquals("1", sw.getDPID());

		port = op.searchPort("2", (short) 1);
		assertNotNull(port);
		assertTrue(port.getNumber() == 1);
		sw = port.getSwitch();
		assertNotNull(sw);
		assertEquals("2", sw.getDPID());

		port = op.searchPort("2", (short) 2);
		assertNotNull(port);
		assertTrue(port.getNumber() == 2);
		sw = port.getSwitch();
		assertNotNull(sw);
		assertEquals("2", sw.getDPID());
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#removePort(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject)}.
	 */
	@Test
	public final void testRemovePort() {
		ISwitchObject sw;
		IPortObject port;
		
		sw = op.newSwitch("1");
		sw.addPort(op.newPort((short) 1));
		sw.addPort(op.newPort((short) 2));
		
		op.commit();

		port = op.searchPort("1", (short) 1);
		assertNotNull(port);
		assertNotNull(op.searchPort("1", (short) 2));
		assertNull(op.searchPort("1", (short) 3));

		op.removePort(port);
		op.commit();
		
		assertNull(op.searchPort("1", (short) 1));
		port = op.searchPort("1", (short) 2);
		assertNotNull(port);
		
		op.removePort(port);
		op.commit();

		assertNull(op.searchPort("1", (short) 1));
		assertNull(op.searchPort("1", (short) 2));
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#newDevice(net.onrc.onos.util.GraphDBConnection)}.
	 */
	@Test
	public final void testNewDevice() {
		assertFalse(testdb.getVertices("type", "device").iterator().hasNext());
		
		IDeviceObject device = op.newDevice();
		device.setMACAddress("11:22:33:44:55:66");
		device.setIPAddress("192.168.1.1");
		op.commit();
		
		Iterator<Vertex> vertices = testdb.getVertices("type", "device").iterator();
		assertTrue(vertices.hasNext());
		Vertex v = vertices.next();
		assertEquals("11:22:33:44:55:66", v.getProperty("dl_addr").toString());
		assertEquals("192.168.1.1", v.getProperty("nw_addr").toString());
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchDevice(net.onrc.onos.util.GraphDBConnection, java.lang.String)}.
	 */
	@Test
	public final void testSearchDevice() {
		assertNull(op.searchDevice("11:22:33:44:55:66"));
		assertNull(op.searchDevice("66:55:44:33:22:11"));

		op.newDevice().setMACAddress("11:22:33:44:55:66");
		op.commit();
		
		IDeviceObject device = op.searchDevice("11:22:33:44:55:66");
		assertNotNull(device);
		assertEquals("11:22:33:44:55:66", device.getMACAddress());
		
		assertNull(op.searchDevice("66:55:44:33:22:11"));
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getDevices(net.onrc.onos.util.GraphDBConnection)}.
	 */
	@Test
	public final void testGetDevices() {
		List<String> original_macs = Arrays.asList(
				"11:11:11:11:11:11",
				"22:22:22:22:22:22",
				"33:33:33:33:33:33"
				);
		
		for (String mac: original_macs) op.newDevice().setMACAddress(mac);
		op.commit();
		
		Iterable<IDeviceObject> devices = op.getDevices();
		List<String> macs = new ArrayList<String>();
		for (IDeviceObject device: devices) macs.add(device.getMACAddress());
		Collections.sort(macs);
		assertArrayEquals(original_macs.toArray(), macs.toArray());
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#removeDevice(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject)}.
	 */
	@Test
	public final void testRemoveDevice() {
		op.newDevice().setMACAddress("11:22:33:44:55:66");
		op.commit();
		
		op.removeDevice(op.searchDevice("11:22:33:44:55:66"));
		op.commit();
		assertNull(op.searchDevice("11:22:33:44:55:66"));
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#newFlowPath(net.onrc.onos.util.GraphDBConnection)}.
	 */
	@Test
	public final void testNewFlowPath() {
		FlowId flowId = new FlowId(10);
		IFlowPath flowPath = op.newFlowPath();
		flowPath.setFlowId(flowId.toString());
		op.commit();

		Iterator<IFlowPath> flows = op.getAllFlowPaths().iterator();
		assertTrue(flows.hasNext());
		assertEquals(flowId.toString(), flows.next().getFlowId());
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchFlowPath(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.util.FlowId)}.
	 */
	@Test
	public final void testSearchFlowPath() {
		FlowId flowId = new FlowId(20);
		assertNull(op.searchFlowPath(flowId));

		op.newFlowPath().setFlowId(flowId.toString());
		op.commit();
		
		IFlowPath flowPath = op.searchFlowPath(flowId);
		assertNotNull(flowPath);
		assertEquals(flowId.toString(), flowPath.getFlowId());
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getFlowPathByFlowEntry(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry)}.
	 */
	@Test
	public final void testGetFlowPathByFlowEntry() {
		FlowId flowId10 = new FlowId(10);
		FlowId flowId20 = new FlowId(20);
		IFlowPath flowPath10 = op.newFlowPath();
		IFlowPath flowPath20 = op.newFlowPath();
		IFlowEntry flowEntry10 = op.newFlowEntry();
		IFlowEntry flowEntry20 = op.newFlowEntry();
		IFlowEntry flowEntry30 = op.newFlowEntry();
		FlowEntryId flowEntryId10 = new FlowEntryId(10); 
		FlowEntryId flowEntryId20 = new FlowEntryId(20); 
		FlowEntryId flowEntryId30 = new FlowEntryId(30); 
		flowEntry10.setFlowEntryId(flowEntryId10.toString());
		flowEntry20.setFlowEntryId(flowEntryId20.toString());
		flowEntry30.setFlowEntryId(flowEntryId30.toString());
		flowPath10.setFlowId(flowId10.toString());
		flowPath10.addFlowEntry(flowEntry10);
		flowPath20.setFlowId(flowId20.toString());
		flowPath20.addFlowEntry(flowEntry20);
		op.commit();

		flowEntry10 = op.searchFlowEntry(flowEntryId10);
		IFlowPath obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry10);
		assertNotNull(obtainedFlowPath);
		assertEquals(flowId10.toString(), obtainedFlowPath.getFlowId());
		
		flowEntry20 = op.searchFlowEntry(flowEntryId20);
		obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry20);
		assertNotNull(obtainedFlowPath);
		assertEquals(flowId20.toString(), obtainedFlowPath.getFlowId());
		
		flowEntry30 = op.searchFlowEntry(flowEntryId30);
		obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry30);
		assertNull(obtainedFlowPath);
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getAllFlowPaths(net.onrc.onos.util.GraphDBConnection)}.
	 */
	@Test
	public final void testGetAllFlowPaths() {
		List<FlowId> flowids = Arrays.asList(
				new FlowId(10), new FlowId(20), new FlowId(30)
				);
		
		for (FlowId flowId: flowids)
			op.newFlowPath().setFlowId(flowId.toString());
		op.commit();

		List<String> actual_ids = new ArrayList<String>();
		for (IFlowPath flowPath: op.getAllFlowPaths()) actual_ids.add(flowPath.getFlowId());
		Collections.sort(actual_ids);

		List<String> expected_ids = new ArrayList<String>();
		for (FlowId flowid: flowids) expected_ids.add(flowid.toString());
		Collections.sort(expected_ids);
		
		assertArrayEquals(expected_ids.toArray(), actual_ids.toArray());
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#removeFlowPath(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath)}.
	 */
	@Test
	public final void testRemoveFlowPath() {
		FlowId flowId10 = new FlowId(10);
		FlowId flowId20 = new FlowId(20);
		op.newFlowPath().setFlowId(flowId10.toString());
		op.newFlowPath().setFlowId(flowId20.toString());
		op.commit();
		
		IFlowPath flowPath = op.searchFlowPath(flowId10);
		assertNotNull(flowPath);
		op.removeFlowPath(flowPath);
		op.commit();
		
		assertNull(op.searchFlowPath(flowId10));
		assertNotNull(op.searchFlowPath(flowId20));
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#newFlowEntry(net.onrc.onos.util.GraphDBConnection)}.
	 */
	@Test
	public final void testNewFlowEntry() {
		IFlowEntry flowEntry = op.newFlowEntry();
		FlowEntryId flowEntryId = new FlowEntryId();
		flowEntryId.setValue(12345);
		flowEntry.setFlowEntryId(flowEntryId.toString());
		op.commit();
		
		flowEntry = op.searchFlowEntry(flowEntryId);
		assertNotNull(flowEntry);
		assertEquals(flowEntry.getFlowEntryId(), flowEntryId.toString());		
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchFlowEntry(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.util.FlowEntryId)}.
	 */
	@Test
	public final void testSearchFlowEntry() {
		FlowEntryId flowEntryId10 = new FlowEntryId();
		flowEntryId10.setValue(10);
		FlowEntryId flowEntryId20 = new FlowEntryId();
		flowEntryId20.setValue(20);
		FlowEntryId flowEntryId30 = new FlowEntryId();
		flowEntryId30.setValue(30);
		
		op.newFlowEntry().setFlowEntryId(flowEntryId10.toString());
		op.newFlowEntry().setFlowEntryId(flowEntryId20.toString());
		op.commit();
		
		assertNull(op.searchFlowEntry(flowEntryId30));
		IFlowEntry flowEntry = op.searchFlowEntry(flowEntryId10);
		assertEquals(flowEntry.getFlowEntryId(), flowEntryId10.toString());
		flowEntry = op.searchFlowEntry(flowEntryId20);
		assertEquals(flowEntry.getFlowEntryId(), flowEntryId20.toString());
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getAllFlowEntries(net.onrc.onos.util.GraphDBConnection)}.
	 */
	@Test
	public final void testGetAllFlowEntries() {
		List<FlowEntryId> flowEntryIds = Arrays.asList(
				new FlowEntryId(10), new FlowEntryId(20), new FlowEntryId(30)
				);
		
		for (FlowEntryId flowEntryId: flowEntryIds)
			op.newFlowEntry().setFlowEntryId(flowEntryId.toString());
		op.commit();

		List<String> actual_ids = new ArrayList<String>();
		for (IFlowEntry flowEntry: op.getAllFlowEntries()) actual_ids.add(flowEntry.getFlowEntryId());
		Collections.sort(actual_ids);

		List<String> expected_ids = new ArrayList<String>();
		for (FlowEntryId flowEntryId: flowEntryIds) expected_ids.add(flowEntryId.toString());
		Collections.sort(expected_ids);
		
		assertArrayEquals(expected_ids.toArray(), actual_ids.toArray());
	}

	/**
	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#removeFlowEntry(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry)}.
	 */
	@Test
	public final void testRemoveFlowEntry() {
		FlowEntryId flowEntryId10 = new FlowEntryId(10);
		FlowEntryId flowEntryId20 = new FlowEntryId(20);
		op.newFlowEntry().setFlowEntryId(flowEntryId10.toString());
		op.newFlowEntry().setFlowEntryId(flowEntryId20.toString());
		op.commit();
		
		IFlowEntry flowEntry = op.searchFlowEntry(flowEntryId10);
		assertNotNull(flowEntry);
		op.removeFlowEntry(flowEntry);
		op.commit();
		
		assertNull(op.searchFlowEntry(flowEntryId10));
		assertNotNull(op.searchFlowEntry(flowEntryId20));
	}

}
