package net.onrc.onos.ofcontroller.networkgraph;

import java.net.InetAddress;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import net.floodlightcontroller.util.MACAddress;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AbstractNetworkGraph implements NetworkGraph {
	@SuppressWarnings("unused")
	private static final Logger log = LoggerFactory.getLogger(AbstractNetworkGraph.class);

	// DPID -> Switch
	protected ConcurrentMap<Long, Switch> switches;

	protected ConcurrentMap<InetAddress, Set<Device>> addr2Device;
	protected ConcurrentMap<MACAddress, Device> mac2Device;

	public AbstractNetworkGraph() {
		// TODO: Does these object need to be stored in Concurrent Collection?
		switches = new ConcurrentHashMap<>();
		addr2Device = new ConcurrentHashMap<>();
		mac2Device = new ConcurrentHashMap<>();
	}

	@Override
	public Switch getSwitch(Long dpid) {
		// TODO Check if it is safe to directly return this Object.
		return switches.get(dpid);
	}

	@Override
	public Iterable<Switch> getSwitches() {
		// TODO Check if it is safe to directly return this Object.
		return Collections.unmodifiableCollection(switches.values());
	}

	@Override
	public Iterable<Link> getLinks() {
		List<Link> linklist = new LinkedList<>();

		for (Switch sw : switches.values()) {
			Iterable<Link> links = sw.getOutgoingLinks();
			for (Link l : links) {
				linklist.add(l);
			}
		}
		return linklist;
	}

	@Override
	public Iterable<Link> getOutgoingLinksFromSwitch(Long dpid) {
		Switch sw = getSwitch(dpid);
		if (sw == null) {
			return Collections.emptyList();
		}
		Iterable<Link> links = sw.getOutgoingLinks();
		if (links instanceof Collection) {
			return Collections.unmodifiableCollection((Collection<Link>) links);
		} else {
			List<Link> linklist = new LinkedList<>();
			for (Link l : links) {
				linklist.add(l);
			}
			return linklist;
		}
	}
	
	@Override
	public Iterable<Link> getIncomingLinksFromSwitch(Long dpid) {
		Switch sw = getSwitch(dpid);
		if (sw == null) {
			return Collections.emptyList();
		}
		Iterable<Link> links = sw.getIncomingLinks();
		if (links instanceof Collection) {
			return Collections.unmodifiableCollection((Collection<Link>) links);
		} else {
			List<Link> linklist = new LinkedList<>();
			for (Link l : links) {
				linklist.add(l);
			}
			return linklist;
		}
	}


	@Override
	public Iterable<Device> getDeviceByIp(InetAddress ipAddress) {
		Set<Device> devices = addr2Device.get(ipAddress);
		if (devices == null) {
			return Collections.emptyList();
		}
		return Collections.unmodifiableCollection(devices);
	}

	@Override
	public Device getDeviceByMac(MACAddress address) {
		return mac2Device.get(address);
	}
}
