/*
 * Copyright 2016-present Open Networking Foundation
 *
 * 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.openstacknetworking.impl;

import com.google.common.base.Strings;
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.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onlab.util.Tools;
import org.onosproject.core.CoreService;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.Device;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation;
import org.onosproject.net.Port;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.host.DefaultHostDescription;
import org.onosproject.net.host.HostDescription;
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.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.openstacknetworking.api.InstancePortAdminService;
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeEvent;
import org.onosproject.openstacknode.api.OpenstackNodeListener;
import org.onosproject.openstacknode.api.OpenstackNodeService;
import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.NetworkType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.net.AnnotationKeys.PORT_NAME;
import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_CREATE_TIME;
import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_NETWORK_ID;
import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_PORT_ID;
import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_SEGMENT_ID;
import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
import static org.onosproject.openstacknetworking.api.Constants.portNamePrefixMap;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;

@Service
@Component(immediate = true)
public final class OpenstackSwitchingHostProvider
        extends AbstractProvider implements HostProvider {

    private final Logger log = LoggerFactory.getLogger(getClass());

    private static final String PORT_NAME_PREFIX_VM = "tap";
    private static final String ERR_ADD_HOST = "Failed to add host: ";
    private static final String SONA_HOST_SCHEME = "sona";

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;

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

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

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

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected OpenstackNetworkService osNetworkService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected OpenstackNodeService osNodeService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected InstancePortAdminService instancePortAdminService;

    private final ExecutorService deviceEventExecutor =
            Executors.newSingleThreadExecutor(groupedThreads(this.getClass().getSimpleName(), "device-event"));
    private final InternalDeviceListener internalDeviceListener =
            new InternalDeviceListener();
    private final InternalOpenstackNodeListener internalNodeListener =
            new InternalOpenstackNodeListener();

    private HostProviderService hostProvider;

    /**
     * Creates OpenStack switching host provider.
     */
    public OpenstackSwitchingHostProvider() {
        super(new ProviderId(SONA_HOST_SCHEME, OPENSTACK_NETWORKING_APP_ID));
    }

    @Activate
    void activate() {
        coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
        deviceService.addListener(internalDeviceListener);
        osNodeService.addListener(internalNodeListener);
        hostProvider = hostProviderRegistry.register(this);

        log.info("Started");
    }

    @Deactivate
    void deactivate() {
        hostProviderRegistry.unregister(this);
        osNodeService.removeListener(internalNodeListener);
        deviceService.removeListener(internalDeviceListener);

        deviceEventExecutor.shutdown();

        log.info("Stopped");
    }

    @Override
    public void triggerProbe(Host host) {
        // no probe is required
    }

    /**
     * Processes port addition event.
     * Once a port addition event is detected, it tries to create a host instance
     * with openstack augmented host information such as networkId, portId,
     * createTime, segmentId and notifies to host provider.
     *
     * @param port port object used in ONOS
     */
    private void processPortAdded(Port port, Device device) {
        // TODO check the node state is COMPLETE
        org.openstack4j.model.network.Port osPort = osNetworkService.port(port);
        if (osPort == null) {
            log.warn(ERR_ADD_HOST + "OpenStack port for {} not found", port);
            return;
        }

        Network osNet = osNetworkService.network(osPort.getNetworkId());
        if (osNet == null) {
            log.warn(ERR_ADD_HOST + "OpenStack network {} not found",
                    osPort.getNetworkId());
            return;
        }

        if (osPort.getFixedIps().isEmpty()) {
            log.warn(ERR_ADD_HOST + "no fixed IP for port {}", osPort.getId());
            return;
        }

        MacAddress mac = MacAddress.valueOf(osPort.getMacAddress());
        HostId hostId = HostId.hostId(mac);

        // typically one openstack port should only be bound to one fix IP address;
        // however, openstack4j binds multiple fixed IPs to one port, this might
        // be a defect of openstack4j implementation

        // TODO: we need to find a way to bind multiple ports from multiple
        // openstack networks into one host sooner or later
        Set<IpAddress> fixedIps = osPort.getFixedIps().stream()
                .map(ip -> IpAddress.valueOf(ip.getIpAddress()))
                .collect(Collectors.toSet());

        // connect point is the combination of switch ID with port number where
        // the host is attached to
        ConnectPoint connectPoint = new ConnectPoint(port.element().id(), port.number());

        long createTime = System.currentTimeMillis();

        // we check whether the host already attached to same locations
        Host host = hostService.getHost(hostId);

        // build host annotations to include a set of meta info from neutron
        DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
                .set(ANNOTATION_NETWORK_ID, osPort.getNetworkId())
                .set(ANNOTATION_PORT_ID, osPort.getId())
                .set(ANNOTATION_CREATE_TIME, String.valueOf(createTime));

        // FLAT typed network does not require segment ID
        if (osNet.getNetworkType() != NetworkType.FLAT) {
            annotations.set(ANNOTATION_SEGMENT_ID, osNet.getProviderSegID());
        }

        // build host description object
        HostDescription hostDesc = new DefaultHostDescription(
                mac,
                VlanId.NONE,
                new HostLocation(connectPoint, createTime),
                fixedIps,
                annotations.build());

        if (host != null) {
            Set<HostLocation> locations = host.locations().stream()
                    .filter(l -> l.deviceId().equals(connectPoint.deviceId()))
                    .filter(l -> l.port().equals(connectPoint.port()))
                    .collect(Collectors.toSet());

            // newly added location is not in the existing location list,
            // therefore, we simply add this into the location list
            if (locations.size() == 0) {
                hostProvider.addLocationToHost(hostId,
                        new HostLocation(connectPoint, createTime));
            }

            // newly added location is in the existing location list,
            // the hostDetected method invocation in turn triggers host Update event
            if (locations.size() == 1) {
                hostProvider.hostDetected(hostId, hostDesc, false);
            }
        } else {
            hostProvider.hostDetected(hostId, hostDesc, false);
        }
    }

    /**
     * Processes port removal event.
     * Once a port removal event is detected, it tries to look for a host
     * instance through host provider by giving connect point information,
     * and vanishes it.
     *
     * @param event device event
     */
    private void processPortRemoved(DeviceEvent event) {
        Port port = event.port();
        ConnectPoint connectPoint = new ConnectPoint(port.element().id(), port.number());

        Set<Host> hosts = hostService.getConnectedHosts(connectPoint);

        hosts.forEach(h -> {
            Optional<HostLocation> hostLocation = h.locations().stream()
                    .filter(l -> l.deviceId().equals(port.element().id()))
                    .filter(l -> l.port().equals(port.number())).findAny();

            // if the host contains only one filtered location, we remove the host
            if (h.locations().size() == 1) {
                hostProvider.hostVanished(h.id());
            }

            // if the host contains multiple locations, we simply remove the
            // host location
            if (h.locations().size() > 1 && hostLocation.isPresent()) {
                hostProvider.removeLocationFromHost(h.id(), hostLocation.get());
            }
        });
    }

    /**
     * An internal device listener which listens the port events generated from
     * OVS integration bridge.
     */
    private class InternalDeviceListener implements DeviceListener {

        @Override
        public boolean isRelevant(DeviceEvent event) {
            Device device = event.subject();
            if (!mastershipService.isLocalMaster(device.id())) {
                // do not allow to proceed without mastership
                return false;
            }
            Port port = event.port();
            if (port == null) {
                return false;
            }
            String portName = port.annotations().value(PORT_NAME);

            return !Strings.isNullOrEmpty(portName) &&
                    (portName.startsWith(PORT_NAME_PREFIX_VM) || isDirectPort(portName));
        }

        private boolean isDirectPort(String portName) {
            return portNamePrefixMap().values().stream().filter(p -> portName.startsWith(p)).findAny().isPresent();
        }

        @Override
        public void event(DeviceEvent event) {
            log.info("Device event occurred with type {}", event.type());
            switch (event.type()) {
                case PORT_UPDATED:
                    if (!event.port().isEnabled()) {
                        portRemovedHelper(deviceEventExecutor, event);
                    } else if (event.port().isEnabled()) {
                        portAddedHelper(deviceEventExecutor, event);
                    }
                    break;
                case PORT_ADDED:
                    portAddedHelper(deviceEventExecutor, event);
                    break;
                case PORT_REMOVED:
                    portRemovedHelper(deviceEventExecutor, event);
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * A helper method which logs the port addition event and performs port
     * addition action.
     *
     * @param executor device executor service
     * @param event device event
     */
    private void portAddedHelper(ExecutorService executor, DeviceEvent event) {
        executor.execute(() -> {
            log.debug("Instance port {} is detected from {}",
                    event.port().annotations().value(PORT_NAME),
                    event.subject().id());
            processPortAdded(event.port(), event.subject());
        });
    }

    /**
     * A helper method which logs the port removal event and performs port
     * removal action.
     *
     * @param executor device executor service
     * @param event device event
     */
    private void portRemovedHelper(ExecutorService executor, DeviceEvent event) {
        executor.execute(() -> {
            log.debug("Instance port {} is removed from {}",
                    event.port().annotations().value(PORT_NAME),
                    event.subject().id());
            processPortRemoved(event);
        });
    }

    private class InternalOpenstackNodeListener implements OpenstackNodeListener {

        @Override
        public boolean isRelevant(OpenstackNodeEvent event) {

            if (event.subject().type() == CONTROLLER) {
                return false;
            }
            // do not allow to proceed without mastership
            Device device = deviceService.getDevice(event.subject().intgBridge());
            if (device == null) {
                return false;
            }
            return mastershipService.isLocalMaster(device.id());
        }

        @Override
        public void event(OpenstackNodeEvent event) {
            OpenstackNode osNode = event.subject();

            switch (event.type()) {
                case OPENSTACK_NODE_COMPLETE:
                    deviceEventExecutor.execute(() -> {
                        log.info("COMPLETE node {} is detected", osNode.hostname());
                        processCompleteNode(event.subject());
                    });
                    break;
                case OPENSTACK_NODE_INCOMPLETE:
                    log.warn("{} is changed to INCOMPLETE state", osNode);
                    break;
                case OPENSTACK_NODE_CREATED:
                case OPENSTACK_NODE_UPDATED:
                case OPENSTACK_NODE_REMOVED:
                    // not reacts to the events other than complete and incomplete states
                    break;
                default:
                    break;
            }
        }

        private void processCompleteNode(OpenstackNode osNode) {
            deviceService.getPorts(osNode.intgBridge()).stream()
                    .filter(port -> port.annotations().value(PORT_NAME)
                            .startsWith(PORT_NAME_PREFIX_VM) &&
                            port.isEnabled())
                    .forEach(port -> {
                        log.debug("Instance port {} is detected from {}",
                                port.annotations().value(PORT_NAME),
                                osNode.hostname());
                        processPortAdded(port,
                                deviceService.getDevice(osNode.intgBridge()));
                    });

            portNamePrefixMap().values().forEach(portNamePrefix -> {
                deviceService.getPorts(osNode.intgBridge()).stream()
                        .filter(port -> port.annotations().value(PORT_NAME)
                                .startsWith(portNamePrefix) &&
                                port.isEnabled())
                        .forEach(port -> {
                            log.debug("Instance port {} is detected from {}",
                                    port.annotations().value(portNamePrefix),
                                    osNode.hostname());
                            processPortAdded(port,
                                    deviceService.getDevice(osNode.intgBridge()));
                        });
            });

            Tools.stream(hostService.getHosts())
                    .filter(host -> deviceService.getPort(
                            host.location().deviceId(),
                            host.location().port()) == null)
                    .forEach(host -> {
                        log.info("Remove stale host {}", host.id());
                        hostProvider.hostVanished(host.id());
                    });
        }
    }
}
