package net.onrc.onos.ofcontroller.core;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.HashMap;

import net.onrc.onos.graph.GraphDBConnection;
import net.onrc.onos.graph.GraphDBOperation;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IIpv4Address;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;

import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Before;
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 org.slf4j.LoggerFactory;

import com.google.common.net.InetAddresses;
import com.thinkaurelius.titan.core.TitanFactory;
import com.thinkaurelius.titan.core.TitanGraph;

//Add Powermock preparation
@RunWith(PowerMockRunner.class)
@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
public class INetMapTopologyObjectsIDeviceObjectTest {
	
	//The test network is ./titan/schema/test-network.xml

	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);

	String conf;
    private GraphDBConnection conn = null;
    private GraphDBOperation ope = null;
    private TitanGraph titanGraph = null;
	
	@Before
	public void setUp() throws Exception {
		conf = "/dummy/path/to/db";
		
		// Make mock cassandra DB
		// Replace TitanFactory.open() to return mock DB
		TestDatabaseManager.deleteTestDatabase();
		titanGraph = TestDatabaseManager.getTestDatabase();
		//TestDatabaseManager.populateTestData(titanGraph);
		PowerMock.mockStatic(TitanFactory.class);
		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
		PowerMock.replay(TitanFactory.class);
		
		conn = GraphDBConnection.getInstance(conf);
		ope = new GraphDBOperation(conn);
	}

	@After
	public void tearDown() throws Exception {
		titanGraph.shutdown();
		TestDatabaseManager.deleteTestDatabase();
	}
	
	/**
	 * Desc:
	 *  Test method for get and set MacAddress method.
	 * Condition:
	 *  N/A
	 * Expect:
	 * 1. Should set the mac address.
	 * 2. Should get the mac address.
	 */
	@Test
	public void testSetGetMacAddress() {
		String macaddr = "00:00:00:00:00:00:0a:07";
		IDeviceObject devObj = ope.newDevice();
		devObj.setMACAddress(macaddr);
		assertEquals(devObj.getMACAddress(), macaddr);
	}
	
	/**
	 * Desc:
	 *  Test method for get and set IPAddress method.
	 * Condition:
	 *  N/A
	 * Expect:
	 * 1. Should set the ip address.
	 * 2. Should get the ip address.
	 */
	@Test
	public void testSetGetIPAddress() {
		int ipaddr = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.0.1"));
		IDeviceObject devObj = ope.newDevice();
		IIpv4Address ipv4Address = ope.newIpv4Address();
		ipv4Address.setIpv4Address(ipaddr);
		devObj.addIpv4Address(ipv4Address);
		assertEquals(devObj.getIpv4Address(ipaddr), ipv4Address);
	}
	
	/**
	 * Desc:
	 *  Test method for get attached port.
	 * Condition:
	 *  N/A
	 * Expect:
	 * 1. Should get the attached ports.
	 */
	@Test
	public void testGetAttachedPort() {
		String dpid = "00:00:00:00:00:00:0a:07";
		Short number = 1;	
		Short number2 = 2;
		IPortObject portObj = ope.newPort(dpid, number);
		IPortObject portObj2 = ope.newPort(dpid, number2);
		
		IDeviceObject devObj = ope.newDevice();
		
		portObj.setDevice(devObj);
		portObj2.setDevice(devObj);
		
		HashMap<Short, IPortObject> portObjectList = new HashMap<Short, IPortObject>();
		for(IPortObject port : devObj.getAttachedPorts())
		{
			portObjectList.put(port.getNumber(), port);
		}
		
		assertTrue(portObjectList.containsValue(portObj));
		assertTrue(portObjectList.containsValue(portObj2));
		
	}
	
	/**
	 * Desc:
	 *  Test method for set and remove host port method.
	 * Condition:
	 *  N/A
	 * Expect:
	 * 1. Should set host port from the device.
	 * 2. Should remove host port from the device.
	 */
	@Test
	public void testSetRemoveHostPort() {
		String dpid = "00:00:00:00:00:00:0a:07";
		Short number = 1;	
		IPortObject portObj = ope.newPort(dpid, number);
		
		IDeviceObject devObj = ope.newDevice();
		
		devObj.setHostPort(portObj);
		
		HashMap<String, IDeviceObject> portObjectList = new HashMap<String, IDeviceObject>();
		for(IDeviceObject dev : portObj.getDevices())
		{
			portObjectList.put(dev.getMACAddress(), dev);
		}
		assertTrue(portObjectList.containsValue(devObj));
		
		devObj.removeHostPort(portObj);
		
		HashMap<String, IDeviceObject> portObjectList2 = new HashMap<String, IDeviceObject>();
		for(IDeviceObject dev : portObj.getDevices())
		{
			portObjectList2.put(dev.getMACAddress(), dev);
		}
		assertTrue(!portObjectList2.containsValue(devObj));
	}
	
	/**
	 * Desc:
	 *  Test method for getSwitch method.
	 * Condition:
	 *  N/A
	 * Expect:
	 * 1. Should get the switch connected to the device.
	 */
	@Test
	public void testGetSwitches() {
		String dpid = "00:00:00:00:00:00:0a:07";
		String dpid2 = "00:00:00:00:00:00:0a:08";
		Short number = 1;	
		Short number2 = 2;	
		ISwitchObject swObj = ope.newSwitch(dpid);
		ISwitchObject swObj2 = ope.newSwitch(dpid2);
		IPortObject portObj = ope.newPort(dpid, number);
		IPortObject portObj2 = ope.newPort(dpid2, number2);
		swObj.addPort(portObj);
		swObj2.addPort(portObj2);
		IDeviceObject devObj = ope.newDevice();
		portObj.setDevice(devObj);
		portObj2.setDevice(devObj);
		
		HashMap<String, ISwitchObject> switchObjectList = new HashMap<String, ISwitchObject>();
		for(ISwitchObject sw : devObj.getSwitch())
		{
			switchObjectList.put(sw.getDPID(), sw);
		}
		assertTrue(switchObjectList.containsValue(swObj));
		assertTrue(switchObjectList.containsValue(swObj2));
	}
	
	
}