/*
 * Copyright 2015-present Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.onosproject.provider.nil;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.NodeId;
import org.onosproject.mastership.MastershipAdminService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceAdminService;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.flow.FlowRuleProviderRegistry;
import org.onosproject.net.flow.FlowRuleProviderService;
import org.onosproject.net.host.HostProvider;
import org.onosproject.net.host.HostProviderRegistry;
import org.onosproject.net.host.HostProviderService;
import org.onosproject.net.host.HostService;
import org.onosproject.net.link.LinkProvider;
import org.onosproject.net.link.LinkProviderRegistry;
import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.link.LinkService;
import org.onosproject.net.packet.PacketProviderRegistry;
import org.onosproject.net.packet.PacketProviderService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;

import java.util.Dictionary;
import java.util.Objects;
import java.util.Properties;

import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onlab.util.Tools.delay;
import static org.onlab.util.Tools.get;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.MastershipRole.MASTER;
import static org.onosproject.net.MastershipRole.NONE;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Provider of a fake network environment, i.e. devices, links, hosts, etc.
 * To be used for benchmarking only.
 */
@Component(immediate = true)
@Service(value = NullProviders.class)
public class NullProviders {

    private static final Logger log = getLogger(NullProviders.class);

    static final String SCHEME = "null";
    static final String PROVIDER_ID = "org.onosproject.provider.nil";

    private static final String FORMAT =
            "Settings: enabled={}, topoShape={}, deviceCount={}, " +
                    "hostCount={}, packetRate={}, mutationRate={}";


    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ClusterService clusterService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected MastershipAdminService mastershipService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ComponentConfigService cfgService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceAdminService deviceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected HostService hostService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected LinkService linkService;


    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceProviderRegistry deviceProviderRegistry;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected HostProviderRegistry hostProviderRegistry;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected LinkProviderRegistry linkProviderRegistry;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected FlowRuleProviderRegistry flowRuleProviderRegistry;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PacketProviderRegistry packetProviderRegistry;

    private final NullDeviceProvider deviceProvider = new NullDeviceProvider();
    private final NullLinkProvider linkProvider = new NullLinkProvider();
    private final NullHostProvider hostProvider = new NullHostProvider();
    private final NullFlowRuleProvider flowRuleProvider = new NullFlowRuleProvider();
    private final NullPacketProvider packetProvider = new NullPacketProvider();
    private final TopologyMutationDriver topologyMutationDriver = new TopologyMutationDriver();

    private DeviceProviderService deviceProviderService;
    private HostProviderService hostProviderService;
    private LinkProviderService linkProviderService;
    private FlowRuleProviderService flowRuleProviderService;
    private PacketProviderService packetProviderService;

    private TopologySimulator simulator;

    @Property(name = "enabled", boolValue = false,
            label = "Enables or disables the provider")
    private boolean enabled = false;

    private static final String DEFAULT_TOPO_SHAPE = "configured";
    @Property(name = "topoShape", value = DEFAULT_TOPO_SHAPE,
            label = "Topology shape: configured, linear, reroute, tree, spineleaf, mesh, grid")
    private String topoShape = DEFAULT_TOPO_SHAPE;

    private static final int DEFAULT_DEVICE_COUNT = 10;
    @Property(name = "deviceCount", intValue = DEFAULT_DEVICE_COUNT,
            label = "Number of devices to generate")
    private int deviceCount = DEFAULT_DEVICE_COUNT;

    private static final int DEFAULT_HOST_COUNT = 5;
    @Property(name = "hostCount", intValue = DEFAULT_HOST_COUNT,
            label = "Number of host to generate per device")
    private int hostCount = DEFAULT_HOST_COUNT;

    private static final int DEFAULT_PACKET_RATE = 0;
    @Property(name = "packetRate", intValue = DEFAULT_PACKET_RATE,
            label = "Packet-in/s rate; 0 for no packets")
    private int packetRate = DEFAULT_PACKET_RATE;

    private static final double DEFAULT_MUTATION_RATE = 0;
    @Property(name = "mutationRate", doubleValue = DEFAULT_MUTATION_RATE,
            label = "Link event/s topology mutation rate; 0 for no mutations")
    private double mutationRate = DEFAULT_MUTATION_RATE;

    private static final String DEFAULT_MASTERSHIP = "random";
    @Property(name = "mastership", value = DEFAULT_MASTERSHIP,
            label = "Mastership given as 'random' or 'node1=dpid,dpid/node2=dpid,...'")
    private String mastership = DEFAULT_MASTERSHIP;


    @Activate
    public void activate() {
        cfgService.registerProperties(getClass());

        deviceProviderService = deviceProviderRegistry.register(deviceProvider);
        hostProviderService = hostProviderRegistry.register(hostProvider);
        linkProviderService = linkProviderRegistry.register(linkProvider);
        flowRuleProviderService = flowRuleProviderRegistry.register(flowRuleProvider);
        packetProviderService = packetProviderRegistry.register(packetProvider);
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        cfgService.unregisterProperties(getClass(), false);
        tearDown();

        deviceProviderRegistry.unregister(deviceProvider);
        hostProviderRegistry.unregister(hostProvider);
        linkProviderRegistry.unregister(linkProvider);
        flowRuleProviderRegistry.unregister(flowRuleProvider);
        packetProviderRegistry.unregister(packetProvider);

        deviceProviderService = null;
        hostProviderService = null;
        linkProviderService = null;
        flowRuleProviderService = null;
        packetProviderService = null;

        log.info("Stopped");
    }

    @Modified
    public void modified(ComponentContext context) {
        Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();

        boolean newEnabled;
        int newDeviceCount, newHostCount, newPacketRate;
        double newMutationRate;
        String newTopoShape, newMastership;
        try {
            String s = get(properties, "enabled");
            newEnabled = isNullOrEmpty(s) ? enabled : Boolean.parseBoolean(s.trim());

            newTopoShape = get(properties, "topoShape");
            newMastership = get(properties, "mastership");

            s = get(properties, "deviceCount");
            newDeviceCount = isNullOrEmpty(s) ? deviceCount : Integer.parseInt(s.trim());

            s = get(properties, "hostCount");
            newHostCount = isNullOrEmpty(s) ? hostCount : Integer.parseInt(s.trim());

            s = get(properties, "packetRate");
            newPacketRate = isNullOrEmpty(s) ? packetRate : Integer.parseInt(s.trim());

            s = get(properties, "mutationRate");
            newMutationRate = isNullOrEmpty(s) ? mutationRate : Double.parseDouble(s.trim());

        } catch (NumberFormatException e) {
            log.warn(e.getMessage());
            newEnabled = enabled;
            newTopoShape = topoShape;
            newDeviceCount = deviceCount;
            newHostCount = hostCount;
            newPacketRate = packetRate;
            newMutationRate = mutationRate;
            newMastership = mastership;
        }

        // Any change in the following parameters implies hard restart
        if (newEnabled != enabled || !Objects.equals(newTopoShape, topoShape) ||
                newDeviceCount != deviceCount || newHostCount != hostCount) {
            enabled = newEnabled;
            topoShape = newTopoShape;
            deviceCount = newDeviceCount;
            hostCount = newHostCount;
            packetRate = newPacketRate;
            mutationRate = newMutationRate;
            restartSimulation();
        }

        // Any change in the following parameters implies just a rate change
        if (newPacketRate != packetRate || newMutationRate != mutationRate) {
            packetRate = newPacketRate;
            mutationRate = newMutationRate;
            adjustRates();
        }

        // Any change in mastership implies just reassignments.
        if (!Objects.equals(newMastership, mastership)) {
            mastership = newMastership;
            reassignMastership();
        }

        log.info(FORMAT, enabled, topoShape, deviceCount, hostCount,
                 packetRate, mutationRate);
    }

    /**
     * Returns the currently active topology simulator.
     *
     * @return current simulator; null if none is active
     */
    public TopologySimulator currentSimulator() {
        return simulator;
    }

    /**
     * Severs the link between the specified end-points in both directions.
     *
     * @param one link endpoint
     * @param two link endpoint
     */
    public void severLink(ConnectPoint one, ConnectPoint two) {
        if (enabled) {
            topologyMutationDriver.severLink(one, two);
        }
    }

    /**
     * Severs the link between the specified end-points in both directions.
     *
     * @param one link endpoint
     * @param two link endpoint
     */
    public void repairLink(ConnectPoint one, ConnectPoint two) {
        if (enabled) {
            topologyMutationDriver.repairLink(one, two);
        }
    }

    /**
     * Fails the specified device.
     *
     * @param deviceId device identifier
     */
    public void failDevice(DeviceId deviceId) {
        if (enabled) {
            topologyMutationDriver.failDevice(deviceId);
        }
    }

    /**
     * Repairs the specified device.
     *
     * @param deviceId device identifier
     */
    public void repairDevice(DeviceId deviceId) {
        if (enabled) {
            topologyMutationDriver.repairDevice(deviceId);
        }
    }


    // Resets simulation based on the current configuration parameters.
    private void restartSimulation() {
        tearDown();
        if (enabled) {
            setUp();
        }
    }

    // Sets up the topology simulation and all providers.
    private void setUp() {
        simulator = selectSimulator(topoShape);
        simulator.init(topoShape, deviceCount, hostCount,
                       new DefaultServiceDirectory(),
                       deviceProviderService, hostProviderService,
                       linkProviderService);
        flowRuleProvider.start(flowRuleProviderService);
        packetProvider.start(packetRate, hostService, deviceService,
                             packetProviderService);
        simulator.setUpTopology();
        topologyMutationDriver.start(mutationRate, linkService, deviceService,
                                     linkProviderService, deviceProviderService,
                                     simulator);
    }

    // Selects the simulator based on the specified name.
    private TopologySimulator selectSimulator(String topoShape) {
        if (topoShape.matches("linear([,].*|$)")) {
            return new LinearTopologySimulator();
        } else if (topoShape.matches("centipede([,].*|$)")) {
            return new CentipedeTopologySimulator();
        } else if (topoShape.matches("reroute([,].*|$)")) {
            return new RerouteTopologySimulator();
        } else if (topoShape.matches("tree([,].*|$)")) {
            return new TreeTopologySimulator();
        } else if (topoShape.matches("agglink([,].*|$)")) {
            return new AggLinkTopologySimulator();
        } else if (topoShape.matches("spineleaf([,].*|$)")) {
            return new SpineLeafTopologySimulator();
        } else if (topoShape.matches("mesh([,].*|$)")) {
            return new MeshTopologySimulator();
        } else if (topoShape.matches("grid([,].*|$)")) {
            return new GridTopologySimulator();
        } else if (topoShape.matches("fattree([,].*|$)")) {
            return new FatTreeTopologySimulator();
        } else if (topoShape.matches("chordal([,].*|$)")) {
            return new ChordalTopologySimulator();
        } else if (topoShape.matches("custom([,].*|$)")) {
            return new CustomTopologySimulator();
        } else {
            return new ConfiguredTopologySimulator();
        }
    }

    // Shuts down the topology simulator and all providers.
    private void tearDown() {
        if (simulator != null) {
            topologyMutationDriver.stop();
            packetProvider.stop();
            flowRuleProvider.stop();
            delay(500);
            simulator.tearDownTopology();
            simulator = null;
        }
    }

    // Changes packet and mutation rates.
    private void adjustRates() {
        packetProvider.adjustRate(packetRate);
        topologyMutationDriver.adjustRate(mutationRate);
    }

    // Re-assigns mastership roles.
    private void reassignMastership() {
        if (mastership.equals(DEFAULT_MASTERSHIP)) {
            mastershipService.balanceRoles();
        } else {
            NodeId localNode = clusterService.getLocalNode().id();
            rejectMastership();
            String[] nodeSpecs = mastership.split("/");
            for (int i = 0; i < nodeSpecs.length; i++) {
                String[] specs = nodeSpecs[i].split("=");
                if (specs[0].equals(localNode.toString())) {
                    String[] ids = specs[1].split(",");
                    for (String id : ids) {
                        mastershipService.setRole(localNode, deviceId(id), MASTER);
                    }
                    break;
                }
            }
        }
    }

    // Rejects mastership of all devices.
    private void rejectMastership() {
        NodeId localNode = clusterService.getLocalNode().id();
        deviceService.getDevices()
                .forEach(device -> mastershipService.setRole(localNode, device.id(),
                                                             NONE));
    }

    // Null provider base class.
    abstract static class AbstractNullProvider extends AbstractProvider {
        protected AbstractNullProvider() {
            super(new ProviderId(SCHEME, PROVIDER_ID));
        }
    }

    // Device provider facade.
    private class NullDeviceProvider extends AbstractNullProvider implements DeviceProvider {
        @Override
        public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
            deviceProviderService.receivedRoleReply(deviceId, newRole, newRole);
        }

        @Override
        public boolean isReachable(DeviceId deviceId) {
            return topoShape.equals("custom") ||
                    (simulator != null && simulator.contains(deviceId) &&
                            topologyMutationDriver.isReachable(deviceId));
        }

        @Override
        public void triggerProbe(DeviceId deviceId) {
        }

        @Override
        public void changePortState(DeviceId deviceId, PortNumber portNumber,
                                    boolean enable) {
            // TODO maybe required
        }
    }

    // Host provider facade.
    private class NullHostProvider extends AbstractNullProvider implements HostProvider {
        @Override
        public void triggerProbe(Host host) {
        }
    }

    // Host provider facade.
    private class NullLinkProvider extends AbstractNullProvider implements LinkProvider {
    }

}
