/*
 * Copyright 2015-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.vpls;

import com.google.common.collect.ImmutableSet;
import org.onosproject.codec.CodecService;
import org.onosproject.net.EncapsulationType;
import org.onosproject.net.Host;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostService;
import org.onosproject.net.intf.Interface;
import org.onosproject.net.intf.InterfaceService;
import org.onosproject.store.StoreDelegate;
import org.onosproject.vpls.api.Vpls;
import org.onosproject.vpls.api.VplsData;
import org.onosproject.vpls.api.VplsOperation;
import org.onosproject.vpls.api.VplsOperationService;
import org.onosproject.vpls.api.VplsStore;
import org.onosproject.vpls.rest.VplsCodec;
import org.onosproject.vpls.store.VplsStoreEvent;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.slf4j.Logger;

import java.util.Collection;
import java.util.Set;

import static java.util.Objects.requireNonNull;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Application to create L2 broadcast overlay networks using VLANs.
 */
@Component(immediate = true, service = Vpls.class)
public class VplsManager implements Vpls {
    public static final String VPLS_APP = "org.onosproject.vpls";
    private static final String UNSUPPORTED_STORE_EVENT_TYPE =
            "Unsupported store event type {}.";
    private final Logger log = getLogger(getClass());

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected InterfaceService interfaceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected VplsStore vplsStore;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected VplsOperationService operationService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected CodecService codecService;

    private StoreDelegate<VplsStoreEvent> vplsStoreDelegate;
    private HostListener vplsHostListener;


    @Activate
    public void activate() {
        vplsStoreDelegate = new VplsStoreDelegate();
        vplsHostListener = new VplsHostListener();

        vplsStore.setDelegate(vplsStoreDelegate);
        hostService.addListener(vplsHostListener);
        codecService.registerCodec(VplsData.class, new VplsCodec());
    }

    @Deactivate
    public void deactivate() {
        vplsStore.unsetDelegate(vplsStoreDelegate);
        hostService.removeListener(vplsHostListener);
        codecService.unregisterCodec(VplsData.class);
    }

    @Override
    public VplsData createVpls(String vplsName, EncapsulationType encapsulationType) {
        requireNonNull(vplsName);
        requireNonNull(encapsulationType);

        if (vplsStore.getVpls(vplsName) != null) {
            return null;
        }

        VplsData vplsData = VplsData.of(vplsName, encapsulationType);
        vplsStore.addVpls(vplsData);

        return vplsData;
    }

    @Override
    public VplsData removeVpls(VplsData vplsData) {
        requireNonNull(vplsData);
        VplsData newData = VplsData.of(vplsData);
        newData.state(VplsData.VplsState.REMOVING);
        vplsStore.removeVpls(vplsData);
        return vplsData;
    }

    @Override
    public void addInterfaces(VplsData vplsData, Collection<Interface> interfaces) {
        requireNonNull(vplsData);
        requireNonNull(interfaces);
        VplsData newData = VplsData.of(vplsData);
        newData.addInterfaces(interfaces);
        updateVplsStatus(newData, VplsData.VplsState.UPDATING);
    }

    @Override
    public void addInterface(VplsData vplsData, Interface iface) {
        requireNonNull(vplsData);
        requireNonNull(iface);
        VplsData newData = VplsData.of(vplsData);
        newData.addInterface(iface);
        updateVplsStatus(newData, VplsData.VplsState.UPDATING);
    }

    @Override
    public void setEncapsulationType(VplsData vplsData, EncapsulationType encapsulationType) {
        requireNonNull(vplsData);
        requireNonNull(encapsulationType);
        VplsData newData = VplsData.of(vplsData);
        if (newData.encapsulationType().equals(encapsulationType)) {
            // Encap type not changed.
            return;
        }
        newData.encapsulationType(encapsulationType);
        updateVplsStatus(newData, VplsData.VplsState.UPDATING);
    }

    @Override
    public VplsData getVpls(String vplsName) {
        requireNonNull(vplsName);
        return vplsStore.getVpls(vplsName);
    }

    @Override
    public Collection<Interface> removeInterfaces(VplsData vplsData, Collection<Interface> interfaces) {
        requireNonNull(vplsData);
        requireNonNull(interfaces);
        VplsData newData = VplsData.of(vplsData);
        newData.removeInterfaces(interfaces);
        updateVplsStatus(newData, VplsData.VplsState.UPDATING);
        return interfaces;
    }

    @Override
    public Interface removeInterface(VplsData vplsData, Interface iface) {
        requireNonNull(vplsData);
        requireNonNull(iface);
        VplsData newData = VplsData.of(vplsData);
        newData.removeInterface(iface);
        updateVplsStatus(newData, VplsData.VplsState.UPDATING);
        return iface;
    }

    @Override
    public void removeAllVpls() {
        Set<VplsData> allVplses = ImmutableSet.copyOf(vplsStore.getAllVpls());
        allVplses.forEach(this::removeVpls);
    }

    @Override
    public Collection<VplsData> getAllVpls() {
        return ImmutableSet.copyOf(vplsStore.getAllVpls());
    }

    /**
     * Updates VPLS status to the store.
     *
     * @param vplsData the VPLS
     * @param vplsState the new state to the VPLS
     */
    private void updateVplsStatus(VplsData vplsData, VplsData.VplsState vplsState) {
        vplsData.state(vplsState);
        vplsStore.updateVpls(vplsData);
    }

    /**
     * A listener for host events.
     * Updates a VPLS if host added or removed.
     */
    class VplsHostListener implements HostListener {
        @Override
        public void event(HostEvent event) {
            Host host = event.subject();
            Interface iface = getHostInterface(host);
            if (iface == null) {
                return;
            }
            VplsData vplsData = vplsStore.getAllVpls().stream()
                    .filter(v -> v.interfaces().contains(iface))
                    .findFirst()
                    .orElse(null);
            if (vplsData == null) {
                // the host does not related to any vpls
                return;
            }
            updateVplsStatus(vplsData, VplsData.VplsState.UPDATING);
        }

        /**
         * Gets the network interface of the host.
         *
         * @param host the host
         * @return the network interface of the host; null if no network
         * interface found
         */
        private Interface getHostInterface(Host host) {
            Set<Interface> interfaces = interfaceService.getInterfaces();
            return interfaces.stream()
                    .filter(iface -> iface.connectPoint().equals(host.location()) &&
                            iface.vlan().equals(host.vlan()))
                    .findFirst()
                    .orElse(null);
        }
    }

    /**
     * Store delegate for VPLS store.
     * Handles VPLS store event and generate VPLS operation according to event
     * type.
     */
    class VplsStoreDelegate implements StoreDelegate<VplsStoreEvent> {

        @Override
        public void notify(VplsStoreEvent event) {
            VplsOperation vplsOperation;
            VplsOperation.Operation op;
            VplsData vplsData = event.subject();
            switch (event.type()) {
                case ADD:
                    op = VplsOperation.Operation.ADD;
                    break;
                case REMOVE:
                    op = VplsOperation.Operation.REMOVE;
                    break;
                case UPDATE:
                    if (vplsData.state() == VplsData.VplsState.FAILED ||
                            vplsData.state() == VplsData.VplsState.ADDED ||
                            vplsData.state() == VplsData.VplsState.REMOVED) {
                        // Update the state only. Nothing to do if it is updated
                        // to ADDED, REMOVED or FAILED
                        op = null;
                    } else {
                        op = VplsOperation.Operation.UPDATE;
                    }
                    break;
                default:
                    log.warn(UNSUPPORTED_STORE_EVENT_TYPE, event.type());
                    return;
            }
            if (op != null) {
                vplsOperation = VplsOperation.of(vplsData, op);
                operationService.submit(vplsOperation);
            }
        }
    }
}
