package net.onrc.onos.registry.controller;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.floodlightcontroller.core.IFloodlightProviderService;
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.restserver.IRestApiService;
import net.onrc.onos.registry.controller.web.RegistryWebRoutable;

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

/**
 * Implementation of a registry that doesn't rely on any external registry
 * service. This is designed to be used only in single-node setups (e.g. for
 * development). All registry data is stored in local memory.
 * @author jono
 *
 */
public class StandaloneRegistry implements IFloodlightModule,
		IControllerRegistryService {
	protected final static Logger log = LoggerFactory.getLogger(StandaloneRegistry.class);
	
	protected IRestApiService restApi;
	
	protected String controllerId = null;
	protected Map<String, ControlChangeCallback> switchCallbacks;
	

	@Override
	public void requestControl(long dpid, ControlChangeCallback cb)
			throws RegistryException {
		if (controllerId == null) {
			throw new RuntimeException(
					"Must register a controller before calling requestControl");
		}
		
		switchCallbacks.put(HexString.toHexString(dpid), cb);
		
		log.debug("Control granted for {}", HexString.toHexString(dpid));
		
		//Immediately grant request for control
		if (cb != null) {
			cb.controlChanged(dpid, true);
		}
	}

	@Override
	public void releaseControl(long dpid) {
		ControlChangeCallback cb = switchCallbacks.remove(HexString.toHexString(dpid));
		
		log.debug("Control released for {}", HexString.toHexString(dpid));
		
		if (cb != null){
			cb.controlChanged(dpid, false);
		}
	}

	@Override
	public boolean hasControl(long dpid) {
		return switchCallbacks.containsKey(HexString.toHexString(dpid));
	}

	@Override
	public boolean isClusterLeader() {
	    return true;
	}

	@Override
	public String getControllerId() {
		return controllerId;
	}

	@Override
	public void registerController(String controllerId)
			throws RegistryException {
		if (this.controllerId != null) {
			throw new RegistryException(
					"Controller already registered with id " + this.controllerId);
		}
		this.controllerId = controllerId;
	}

	@Override
	public Collection<String> getAllControllers() throws RegistryException {
		List<String> l = new ArrayList<String>();
		l.add(controllerId);
		return l;
	}

	@Override
	public String getControllerForSwitch(long dpid) throws RegistryException {
		return (switchCallbacks.get(HexString.toHexString(dpid)) != null)? controllerId: null;
	}

	@Override
	public Map<String, List<ControllerRegistryEntry>> getAllSwitches() {
		Map<String, List<ControllerRegistryEntry>> switches = 
				new HashMap<String, List<ControllerRegistryEntry>>();
		
		for (String strSwitch : switchCallbacks.keySet()){
			log.debug("Switch _{}", strSwitch);
			List<ControllerRegistryEntry> list = new ArrayList<ControllerRegistryEntry>();
			list.add(new ControllerRegistryEntry(controllerId, 0));
			
			switches.put(strSwitch, list);
		}
		
		return switches;
	}

	@Override
	public Collection<Long> getSwitchesControlledByController(
			String controllerId) {
		throw new RuntimeException("Not yet implemented");
	}
	
	private long blockTop = 0L;
	private static final long BLOCK_SIZE = 0x1000000L;
	
	/**
	 * Returns a block of IDs which are unique and unused.
	 * Range of IDs is fixed size and is assigned incrementally as this method called.
	 */
	@Override
	public synchronized IdBlock allocateUniqueIdBlock(){
		long blockHead = blockTop;
		long blockTail = blockTop + BLOCK_SIZE;
		
		IdBlock block = new IdBlock(blockHead, blockTail - 1, BLOCK_SIZE);
		blockTop = blockTail;
		
		return block;
	}

	@Override
	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
		Collection<Class<? extends IFloodlightService>> l = 
				new ArrayList<Class<? extends IFloodlightService>>();
		l.add(IControllerRegistryService.class);
		return l;
	}

	@Override
	public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
		Map<Class<? extends IFloodlightService>, IFloodlightService> m = 
				new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
		m.put(IControllerRegistryService.class,  this);
		return m;
	}

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

	@Override
	public void init(FloodlightModuleContext context)
			throws FloodlightModuleException {
		restApi = context.getServiceImpl(IRestApiService.class);
		
		switchCallbacks = new HashMap<String, ControlChangeCallback>();
	}

	@Override
	public void startUp(FloodlightModuleContext context) {
		restApi.addRestletRoutable(new RegistryWebRoutable());
	}

    @Override
    public IdBlock allocateUniqueIdBlock(long range) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

}
