package net.floodlightcontroller.core.module;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Returns list of modules loaded by Floodlight.
 *
 * @author Rob Sherwood
 */
public class ModuleLoaderResource extends ServerResource {
    protected final static Logger log =
            LoggerFactory.getLogger(ModuleLoaderResource.class);

    /**
     * Retrieves information about loaded modules.
     *
     * @return Information about loaded modules.
     */
    @Get("json")
    public Map<String, Object> retrieve() {
        return retrieveInternal(false);
    }

    /**
     * Retrieves all modules and their dependencies available
     * to Floodlight.
     *
     * @param loadedOnly Whether to return all modules available or only the ones loaded.
     * @return Information about modules available or loaded.
     */
    public Map<String, Object> retrieveInternal(boolean loadedOnly) {
        Map<String, Object> model = new HashMap<String, Object>();

        Set<String> loadedModules = new HashSet<String>();
        for (Object val : getContext().getAttributes().values()) {
            if ((val instanceof IFloodlightModule) || (val instanceof IFloodlightService)) {
                String serviceImpl = val.getClass().getCanonicalName();
                loadedModules.add(serviceImpl);
                // log.debug("Tracking serviceImpl " + serviceImpl);
            }
        }

        for (String moduleName :
                FloodlightModuleLoader.moduleNameMap.keySet()) {
            Map<String, Object> moduleInfo = new HashMap<String, Object>();

            IFloodlightModule module =
                    FloodlightModuleLoader.moduleNameMap.get(
                            moduleName);

            Collection<Class<? extends IFloodlightService>> deps =
                    module.getModuleDependencies();
            if (deps == null)
                deps = new HashSet<Class<? extends IFloodlightService>>();
            Map<String, Object> depsMap = new HashMap<String, Object>();
            for (Class<? extends IFloodlightService> service : deps) {
                Object serviceImpl = getContext().getAttributes().get(service.getCanonicalName());
                if (serviceImpl != null)
                    depsMap.put(service.getCanonicalName(), serviceImpl.getClass().getCanonicalName());
                else
                    depsMap.put(service.getCanonicalName(), "<unresolved>");

            }
            moduleInfo.put("depends", depsMap);

            Collection<Class<? extends IFloodlightService>> provides =
                    module.getModuleServices();
            if (provides == null)
                provides = new HashSet<Class<? extends IFloodlightService>>();
            Map<String, Object> providesMap = new HashMap<String, Object>();
            for (Class<? extends IFloodlightService> service : provides) {
                providesMap.put(service.getCanonicalName(), module.getServiceImpls().get(service).getClass().getCanonicalName());
            }
            moduleInfo.put("provides", providesMap);

            moduleInfo.put("loaded", false);        // not loaded, by default

            // check if this module is loaded directly
            if (loadedModules.contains(module.getClass().getCanonicalName())) {
                moduleInfo.put("loaded", true);
            } else {
                // if not, then maybe one of the services it exports is loaded
                for (Class<? extends IFloodlightService> service : provides) {
                    String modString = module.getServiceImpls().get(service).getClass().getCanonicalName();
                    if (loadedModules.contains(modString))
                        moduleInfo.put("loaded", true);
                                /* else 
                                        log.debug("ServiceImpl not loaded " + modString); */
                }
            }

            if ((Boolean) moduleInfo.get("loaded") || !loadedOnly)
                model.put(moduleName, moduleInfo);
        }
        return model;
    }
}
