package net.onrc.onos.ofcontroller.floodlightlistener;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.core.util.SingletonTask;
import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.onrc.onos.ofcontroller.core.IOFSwitchPortListener;
import net.onrc.onos.ofcontroller.devicemanager.IOnosDeviceListener;
import net.onrc.onos.ofcontroller.devicemanager.IOnosDeviceService;
import net.onrc.onos.ofcontroller.devicemanager.OnosDevice;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
import net.onrc.onos.ofcontroller.networkgraph.DeviceEvent;
import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
import net.onrc.onos.ofcontroller.networkgraph.NetworkGraphDiscoveryInterface;
import net.onrc.onos.ofcontroller.networkgraph.PortEvent;
import net.onrc.onos.ofcontroller.networkgraph.PortEvent.SwitchPort;
import net.onrc.onos.ofcontroller.networkgraph.Switch;
import net.onrc.onos.ofcontroller.networkgraph.SwitchEvent;
import net.onrc.onos.registry.controller.IControllerRegistryService;
import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
import net.onrc.onos.registry.controller.RegistryException;

import org.openflow.protocol.OFPhysicalPort;
import org.openflow.util.HexString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.net.InetAddresses;

public class NetworkGraphPublisher implements /*IOFSwitchListener,*/
												IOFSwitchPortListener,
												ILinkDiscoveryListener,
												IFloodlightModule,
												IOnosDeviceListener {
	private static final Logger log = LoggerFactory.getLogger(NetworkGraphPublisher.class);

	private IFloodlightProviderService floodlightProvider;
	private ILinkDiscoveryService linkDiscovery;
	private IControllerRegistryService registryService;
	private INetworkGraphService networkGraphService;

	private IOnosDeviceService onosDeviceService;

	private NetworkGraph networkGraph;
	private NetworkGraphDiscoveryInterface networkGraphDiscoveryInterface;

	private static final String ENABLE_CLEANUP_PROPERTY = "EnableCleanup";
	private boolean cleanupEnabled = true;
	private static final int CLEANUP_TASK_INTERVAL = 60; // in seconds
	private SingletonTask cleanupTask;

    /**
     *  Cleanup and synch switch state from registry
     */
    private class SwitchCleanup implements ControlChangeCallback, Runnable {
        @Override
        public void run() {
            String old = Thread.currentThread().getName();
            Thread.currentThread().setName("SwitchCleanup@" + old);

            try {
            	log.debug("Running cleanup thread");
                switchCleanup();
            }
            catch (Exception e) {
                log.error("Error in cleanup thread", e);
            } finally {
                cleanupTask.reschedule(CLEANUP_TASK_INTERVAL,
                                          TimeUnit.SECONDS);
                Thread.currentThread().setName(old);
            }
        }

        private void switchCleanup() {
        	Iterable<Switch> switches = networkGraph.getSwitches();

        	log.debug("Checking for inactive switches");
        	// For each switch check if a controller exists in controller registry
        	for (Switch sw: switches) {
    			try {
    				String controller =
    						registryService.getControllerForSwitch(sw.getDpid());
    				if (controller == null) {
    					log.debug("Requesting control to set switch {} INACTIVE",
    							HexString.toHexString(sw.getDpid()));
    					registryService.requestControl(sw.getDpid(), this);
    				}
    			} catch (RegistryException e) {
    				log.error("Caught RegistryException in cleanup thread", e);
    			}
    		}
        }

		@Override
		public void controlChanged(long dpid, boolean hasControl) {
			if (hasControl) {
				log.debug("Got control to set switch {} INACTIVE", HexString.toHexString(dpid));

				SwitchEvent switchEvent = new SwitchEvent(dpid);
				networkGraphDiscoveryInterface.removeSwitchDiscoveryEvent(switchEvent);
			    registryService.releaseControl(dpid);
			}
		}
    }

	@Override
	public void linkDiscoveryUpdate(LDUpdate update) {
		LinkEvent linkEvent = new LinkEvent(update.getSrc(),
				(long)update.getSrcPort(), update.getDst(),
				(long)update.getDstPort());

		switch (update.getOperation()) {
		case LINK_ADDED:
			networkGraphDiscoveryInterface.putLinkDiscoveryEvent(linkEvent);
			break;
		case LINK_UPDATED:
			// We don't use the LINK_UPDATED event (unsure what it means)
			break;
		case LINK_REMOVED:
			networkGraphDiscoveryInterface.removeLinkDiscoveryEvent(linkEvent);
			break;
		default:
			break;
		}
	}

	@Override
	public void switchPortAdded(Long switchId, OFPhysicalPort port) {
		PortEvent portEvent = new PortEvent(switchId, (long)port.getPortNumber());
		networkGraphDiscoveryInterface.putPortDiscoveryEvent(portEvent);
		linkDiscovery.RemoveFromSuppressLLDPs(switchId, port.getPortNumber());
	}

	@Override
	public void switchPortRemoved(Long switchId, OFPhysicalPort port) {
		PortEvent portEvent = new PortEvent(switchId, (long)port.getPortNumber());
		networkGraphDiscoveryInterface.removePortDiscoveryEvent(portEvent);
	}

	@Override
	public void addedSwitch(IOFSwitch sw) {
		// TODO Not very robust
		if (!registryService.hasControl(sw.getId())) {
			return;
		}

		SwitchEvent switchEvent = new SwitchEvent(sw.getId());

		List<PortEvent> portEvents = new ArrayList<PortEvent>();
		for (OFPhysicalPort port : sw.getPorts()) {
			portEvents.add(new PortEvent(sw.getId(), (long)port.getPortNumber()));
		}
		networkGraphDiscoveryInterface
		    .putSwitchDiscoveryEvent(switchEvent, portEvents);

	    for (OFPhysicalPort port : sw.getPorts()) {
			// Allow links to be discovered on this port now that it's
			// in the database
			linkDiscovery.RemoveFromSuppressLLDPs(sw.getId(), port.getPortNumber());
	    }
	}

	@Override
	public void removedSwitch(IOFSwitch sw) {
		// We don't use this event - switch remove is done by cleanup thread
	}

	@Override
	public void switchPortChanged(Long switchId) {
		// We don't use this event
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return null;
	}

	/* *****************
	 * IFloodlightModule
	 * *****************/

	@Override
	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
		return null;
	}

	@Override
	public Map<Class<? extends IFloodlightService>, IFloodlightService>
			getServiceImpls() {
		return null;
	}

	@Override
	public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
		Collection<Class<? extends IFloodlightService>> l =
	            new ArrayList<Class<? extends IFloodlightService>>();
        l.add(IFloodlightProviderService.class);
        l.add(ILinkDiscoveryService.class);
        l.add(IThreadPoolService.class);
        l.add(IControllerRegistryService.class);
        l.add(INetworkGraphService.class);
        l.add(IOnosDeviceService.class);
        return l;
	}

	@Override
	public void init(FloodlightModuleContext context)
			throws FloodlightModuleException {
		floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
		linkDiscovery = context.getServiceImpl(ILinkDiscoveryService.class);
		registryService = context.getServiceImpl(IControllerRegistryService.class);
		onosDeviceService = context.getServiceImpl(IOnosDeviceService.class);

		networkGraphService = context.getServiceImpl(INetworkGraphService.class);
	}

	@Override
	public void startUp(FloodlightModuleContext context) {
		floodlightProvider.addOFSwitchListener(this);
		linkDiscovery.addListener(this);
		onosDeviceService.addOnosDeviceListener(this);

		networkGraph = networkGraphService.getNetworkGraph();
		networkGraphDiscoveryInterface =
				networkGraphService.getNetworkGraphDiscoveryInterface();

		// Run the cleanup thread
		String enableCleanup =
				context.getConfigParams(this).get(ENABLE_CLEANUP_PROPERTY);
		if (enableCleanup != null && enableCleanup.toLowerCase().equals("false")) {
			cleanupEnabled = false;
		}

		log.debug("Cleanup thread is {}enabled", (cleanupEnabled)? "" : "not ");

		if (cleanupEnabled) {
			IThreadPoolService threadPool =
					context.getServiceImpl(IThreadPoolService.class);
			cleanupTask = new SingletonTask(threadPool.getScheduledExecutor(),
					new SwitchCleanup());
			// Run the cleanup task immediately on startup
			cleanupTask.reschedule(0, TimeUnit.SECONDS);
		}
	}

	@Override
	public void onosDeviceAdded(OnosDevice device) {
		log.debug("Called onosDeviceAdded mac {}", device.getMacAddress());

		SwitchPort sp = new SwitchPort(device.getSwitchDPID(), (long)device.getSwitchPort());
		List<SwitchPort> spLists = new ArrayList<SwitchPort>();
		spLists.add(sp);
		DeviceEvent event = new DeviceEvent(device.getMacAddress());
		event.setAttachmentPoints(spLists);
		event.setLastSeenTime(device.getLastSeenTimestamp().getTime());
		if(device.getIpv4Address() != null) {
			InetAddress ip = InetAddresses.fromInteger(device.getIpv4Address());
			event.addIpAddress(ip);
		}
		// Does not use vlan info now.

		networkGraphDiscoveryInterface.putDeviceDiscoveryEvent(event);
	}

	@Override
	public void onosDeviceRemoved(OnosDevice device) {
		log.debug("Called onosDeviceRemoved");
		DeviceEvent event = new DeviceEvent(device.getMacAddress());
		networkGraphDiscoveryInterface.removeDeviceDiscoveryEvent(event);
	}
}
