/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.onrc.onos.graph;

import com.thinkaurelius.titan.core.TitanGraph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.frames.FramedGraph;
import com.tinkerpop.frames.structures.FramedVertexIterable;
import com.tinkerpop.gremlin.java.GremlinPipeline;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
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.IIpv4Address;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.onrc.onos.ofcontroller.core.ISwitchStorage;
import net.onrc.onos.ofcontroller.util.FlowId;

/**
 *
 * @author nickkaranatsios
 */
public abstract class DBOperation implements IDBOperation {

	protected DBConnection conn;

	@Override
	public ISwitchObject searchActiveSwitch(String dpid) {
	    ISwitchObject sw = searchSwitch(dpid);
	    if ((sw != null)
		    && sw.getState().equals(ISwitchStorage.SwitchState.ACTIVE.toString())) {
		return sw;
	    }
	    return null;
	}

	@Override
	public ISwitchObject newSwitch(final String dpid) {
	    ISwitchObject obj = (ISwitchObject) conn.getFramedGraph().addVertex(null, ISwitchObject.class);
	    if (obj != null) {
		obj.setType("switch");
		obj.setDPID(dpid);
	    }
	    return obj;
	}

	@Override
	public Iterable<ISwitchObject> getAllSwitches() {
	    Iterable<ISwitchObject> switches = conn.getFramedGraph().getVertices("type", "switch", ISwitchObject.class);
	    return switches;
	}

	@Override
	public Iterable<ISwitchObject> getInactiveSwitches() {
	    Iterable<ISwitchObject> switches = conn.getFramedGraph().getVertices("type", "switch", ISwitchObject.class);
	    List<ISwitchObject> inactiveSwitches = new ArrayList<ISwitchObject>();

	    for (ISwitchObject sw : switches) {
		if (sw.getState().equals(ISwitchStorage.SwitchState.INACTIVE.toString())) {
		    inactiveSwitches.add(sw);
		}
	    }
	    return inactiveSwitches;
	}

	@Override
	public Iterable<INetMapTopologyObjects.IFlowEntry> getAllSwitchNotUpdatedFlowEntries() {
	    //TODO: Should use an enum for flow_switch_state
	    return conn.getFramedGraph().getVertices("switch_state", "FE_SWITCH_NOT_UPDATED", INetMapTopologyObjects.IFlowEntry.class);

	}

	@Override
	public void removeSwitch(ISwitchObject sw) {
	    conn.getFramedGraph().removeVertex(sw.asVertex());
	}

	@Override
	public IPortObject newPort(String dpid, Short portNum) {
	    IPortObject obj = (IPortObject) conn.getFramedGraph().addVertex(null, IPortObject.class);
	    if (obj != null) {
		obj.setType("port");
		String id = dpid + portNum.toString();
		obj.setPortId(id);
		obj.setNumber(portNum);
	    }
	    return obj;
	}

	/**
	* Create a port having specified port number.
	*
	* @param portNumber port number
	*/
	@Deprecated
	public IPortObject newPort(Short portNumber) {
	    IPortObject obj = (IPortObject) conn.getFramedGraph().addVertex(null, IPortObject.class);
	    if (obj != null) {
		obj.setType("port");
		obj.setNumber(portNumber);
	    }
	    return obj;
	}

	@Override
	public IPortObject searchPort(String dpid, Short number) {
	    String id = dpid + number.toString();
	    return (conn.getFramedGraph() != null && conn.getFramedGraph().getVertices("port_id", id).iterator().hasNext())
		    ? (IPortObject) conn.getFramedGraph().getVertices("port_id", id, IPortObject.class).iterator().next() : null;

	}

	@Override
	public void removePort(IPortObject port) {
	    if (conn.getFramedGraph() != null) {
		conn.getFramedGraph().removeVertex(port.asVertex());
	    }
	}

	@Override
	public IDeviceObject newDevice() {
	    IDeviceObject obj = (IDeviceObject) conn.getFramedGraph().addVertex(null, IDeviceObject.class);
	    if (obj != null) {
		obj.setType("device");
	    }
	    return obj;
	}

	@Override
	public Iterable<IDeviceObject> getDevices() {
	    return conn.getFramedGraph() != null ? conn.getFramedGraph().getVertices("type", "device", IDeviceObject.class) : null;
	}


	@Override
	public void removeDevice(IDeviceObject dev) {
	    if (conn.getFramedGraph() != null) {
		conn.getFramedGraph().removeVertex(dev.asVertex());
	    }
	}
	
	/**
	* Create and return a flow path object.
	*/

	@Override
	public IFlowPath newFlowPath() {
	    IFlowPath flowPath = (IFlowPath)conn.getFramedGraph().addVertex(null, IFlowPath.class);
	    if (flowPath != null) {
		flowPath.setType("flow");
	    }
	    return flowPath;
	}

	@Override
	public IFlowPath getFlowPathByFlowEntry(INetMapTopologyObjects.IFlowEntry flowEntry) {
	    GremlinPipeline<Vertex, IFlowPath> pipe = new GremlinPipeline<Vertex, IFlowPath>();
	    pipe.start(flowEntry.asVertex());
	    pipe.out("flow");
	    FramedVertexIterable<IFlowPath> r = new FramedVertexIterable(conn.getFramedGraph(), (Iterable) pipe, IFlowPath.class);
	    return r.iterator().hasNext() ? r.iterator().next() : null;
	}


	/**
	* Search and get a switch object with DPID.
	*
	* @param dpid DPID of the switch
	*/
	@Override
	public ISwitchObject searchSwitch(final String dpid) {
	    return (conn.getFramedGraph() != null && conn.getFramedGraph().getVertices("dpid", dpid).iterator().hasNext())
		    ? (ISwitchObject) (conn.getFramedGraph().getVertices("dpid", dpid, ISwitchObject.class).iterator().next()) : null;
	}

	@Override
	public Iterable<ISwitchObject> getActiveSwitches() {
	    Iterable<ISwitchObject> switches = conn.getFramedGraph().getVertices("type", "switch", ISwitchObject.class);
	    List<ISwitchObject> activeSwitches = new ArrayList<ISwitchObject>();

	    for (ISwitchObject sw : switches) {
		if (sw.getState().equals(ISwitchStorage.SwitchState.ACTIVE.toString())) {
		    activeSwitches.add(sw);
		}
	    }
	    return activeSwitches;
	}

	@Override
	public IDeviceObject searchDevice(String macAddr) {
	    return (conn.getFramedGraph() != null && conn.getFramedGraph().getVertices("dl_addr", macAddr).iterator().hasNext())
		    ? (IDeviceObject) conn.getFramedGraph().getVertices("dl_addr", macAddr, IDeviceObject.class).iterator().next() : null;

	}

	protected IFlowPath searchFlowPath(final FlowId flowId, final FramedGraph fg) {
	    return fg.getVertices("flow_id", flowId.toString()).iterator().hasNext()
		    ? (IFlowPath) fg.getVertices("flow_id", flowId.toString(),
		    IFlowPath.class).iterator().next() : null;
	}

	protected Iterable<IFlowPath> getAllFlowPaths(final FramedGraph fg) {
	    Iterable<IFlowPath> flowPaths = fg.getVertices("type", "flow", IFlowPath.class);

	    List<IFlowPath> nonNullFlows = new ArrayList<IFlowPath>();

	    for (IFlowPath fp : flowPaths) {
		if (fp.getFlowId() != null) {
		    nonNullFlows.add(fp);
		}
	    }
	    return nonNullFlows;
	}

	@Override
	public IFlowEntry newFlowEntry() {
	    IFlowEntry flowEntry = (IFlowEntry) conn.getFramedGraph().addVertex(null, IFlowEntry.class);
	    if (flowEntry != null) {
		flowEntry.setType("flow_entry");
	    }
	    return flowEntry;
	}


	public IIpv4Address newIpv4Address() {
		return newVertex("ipv4Address", IIpv4Address.class);
	}
	private <T extends IBaseObject> T newVertex(String type, Class<T> vertexType) {
		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
		T newVertex = fg.addVertex(null, vertexType);
		if (newVertex != null) {
			newVertex.setType(type);
		}
		return newVertex;
	}

	public IIpv4Address searchIpv4Address(int intIpv4Address) {
		return searchForVertex("ipv4_address", intIpv4Address, IIpv4Address.class);
	}
	
	
	public IIpv4Address ensureIpv4Address(int intIpv4Address) {
		IIpv4Address ipv4Vertex = searchIpv4Address(intIpv4Address);
		if (ipv4Vertex == null) {
			ipv4Vertex = newIpv4Address();
			ipv4Vertex.setIpv4Address(intIpv4Address);
		}
		return ipv4Vertex;
	}	

	
	private <T> T searchForVertex(String propertyName, Object propertyValue, Class<T> vertexType) {
		if (conn.getFramedGraph() != null) {
			Iterator<T> it = conn.getFramedGraph().getVertices(propertyName, propertyValue, vertexType).iterator();
			if (it.hasNext()) {
				return it.next();
			}
		}
		return null;
	}

	public void removeIpv4Address(IIpv4Address ipv4Address) {
		conn.getFramedGraph().removeVertex(ipv4Address.asVertex());
	}

	
	@Override
	public IDBConnection getDBConnection() {
	    return conn;
	}	
}
