package net.onrc.onos.core.newintent;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

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.api.flowmanager.FlowId;
import net.onrc.onos.api.flowmanager.FlowManagerFloodlightService;
import net.onrc.onos.api.flowmanager.FlowManagerService;
import net.onrc.onos.api.newintent.InstallableIntent;
import net.onrc.onos.api.newintent.Intent;
import net.onrc.onos.api.newintent.IntentCompiler;
import net.onrc.onos.api.newintent.IntentEventListener;
import net.onrc.onos.api.newintent.IntentFloodlightService;
import net.onrc.onos.api.newintent.IntentId;
import net.onrc.onos.api.newintent.IntentInstaller;
import net.onrc.onos.api.newintent.IntentManager;
import net.onrc.onos.api.newintent.IntentOperations;
import net.onrc.onos.api.newintent.IntentState;
import net.onrc.onos.api.newintent.MultiPointToSinglePointIntent;
import net.onrc.onos.api.newintent.PathIntent;
import net.onrc.onos.api.newintent.PointToPointIntent;
import net.onrc.onos.core.datagrid.ISharedCollectionsService;
import net.onrc.onos.core.newintent.web.IntentWebRoutable;
import net.onrc.onos.core.registry.IControllerRegistryService;
import net.onrc.onos.core.topology.ITopologyService;
import net.onrc.onos.core.util.IdBlockAllocator;
import net.onrc.onos.core.util.IdGenerator;

/**
 * A Floodlight module for Intent Service.
 */
public class IntentFloodlightModule implements IntentFloodlightService, IFloodlightModule {
    private IntentManager intentManager;

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

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

    @Override
    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
        return Arrays.asList(
                ISharedCollectionsService.class,
                IControllerRegistryService.class,
                FlowManagerFloodlightService.class,
                ITopologyService.class
        );
    }

    @Override
    public void init(FloodlightModuleContext context) throws FloodlightModuleException {
    }

    @Override
    public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
        intentManager =
                new IntentManagerRuntime(
                        context.getServiceImpl(ISharedCollectionsService.class)
                );

        IdBlockAllocator idBlockAllocator =
                context.getServiceImpl(IControllerRegistryService.class);
        IdGenerator<IntentId> intentIdGenerator =
                new IdBlockAllocatorBasedIntentIdGenerator(idBlockAllocator);
        FlowManagerService flowManagerService =
                context.getServiceImpl(FlowManagerFloodlightService.class);
        IdGenerator<FlowId> flowIdGenerator =
                flowManagerService.getFlowIdGenerator();

        ITopologyService topologyService =
                context.getServiceImpl(ITopologyService.class);

        registerDefaultCompilers(intentIdGenerator, flowIdGenerator, topologyService);
        registerDefaultInstallers(flowManagerService);

        IRestApiService restApi = context.getServiceImpl(IRestApiService.class);
        restApi.addRestletRoutable(new IntentWebRoutable());
    }

    private void registerDefaultCompilers(IdGenerator<IntentId> intentIdGenerator,
                                          IdGenerator<FlowId> flowIdGenerator,
                                          ITopologyService topologyService) {
        intentManager.registerCompiler(PointToPointIntent.class,
                new PointToPointIntentCompiler(intentIdGenerator,
                        flowIdGenerator, topologyService));

        intentManager.registerCompiler(PathIntent.class,
                new PathIntentCompiler(intentIdGenerator, flowIdGenerator));

        intentManager.registerCompiler(MultiPointToSinglePointIntent.class,
                new MultiPointToSinglePointIntentCompiler(intentIdGenerator,
                        flowIdGenerator, topologyService));
    }

    private void registerDefaultInstallers(FlowManagerService flowManagerService) {
        intentManager.registerInstaller(PathFlowIntent.class,
                new PathFlowIntentInstaller(flowManagerService));
        intentManager.registerInstaller(SingleDstTreeFlowIntent.class,
                new SingleDstTreeFlowIntentInstaller(flowManagerService));
        intentManager.registerInstaller(SingleSrcTreeFlowIntent.class,
                new SingleSrcTreeFlowIntentInstaller(flowManagerService));
    }

    /*
     All methods defined in IntentFloodlightService are delegated to IntentManager
     implementation this class has. It helps to reduce the code size of this class
     (IntentModule) and to make IntentManager implementation more testable.
     */
    // All methods below are methods defined in IntentFloodlightService.
    @Override
    public void submit(Intent intent) {
        intentManager.submit(intent);
    }

    @Override
    public void withdraw(Intent intent) {
        intentManager.withdraw(intent);
    }

    @Override
    public void execute(IntentOperations operations) {
        intentManager.execute(operations);
    }

    @Override
    public Set<Intent> getIntents() {
        return intentManager.getIntents();
    }

    @Override
    public Intent getIntent(IntentId id) {
        return intentManager.getIntent(id);
    }

    @Override
    public IntentState getIntentState(IntentId id) {
        return intentManager.getIntentState(id);
    }

    @Override
    public void addListener(IntentEventListener listener) {
        intentManager.addListener(listener);
    }

    @Override
    public void removeListener(IntentEventListener listener) {
        intentManager.removeListener(listener);
    }

    @Override
    public <T extends Intent> void registerCompiler(Class<T> cls, IntentCompiler<T> compiler) {
        intentManager.registerCompiler(cls, compiler);
    }

    @Override
    public <T extends Intent> void unregisterCompiler(Class<T> cls) {
        intentManager.unregisterCompiler(cls);
    }

    @Override
    public Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> getCompilers() {
        return intentManager.getCompilers();
    }

    @Override
    public <T extends InstallableIntent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
        intentManager.registerInstaller(cls, installer);
    }

    @Override
    public <T extends InstallableIntent> void unregisterInstaller(Class<T> cls) {
        intentManager.unregisterInstaller(cls);
    }

    @Override
    public Map<Class<? extends InstallableIntent>, IntentInstaller<? extends InstallableIntent>> getInstallers() {
        return intentManager.getInstallers();
    }
}
