/*
 * 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.incubator.net.tunnel.impl;

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.onosproject.net.provider.AbstractListenerProviderRegistry;
import org.onosproject.core.ApplicationId;
import org.onosproject.incubator.net.tunnel.DefaultTunnel;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.Tunnel.State;
import org.onosproject.incubator.net.tunnel.Tunnel.Type;
import org.onosproject.incubator.net.tunnel.TunnelAdminService;
import org.onosproject.incubator.net.tunnel.TunnelDescription;
import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
import org.onosproject.incubator.net.tunnel.TunnelEvent;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelListener;
import org.onosproject.incubator.net.tunnel.TunnelName;
import org.onosproject.incubator.net.tunnel.TunnelProvider;
import org.onosproject.incubator.net.tunnel.TunnelProviderRegistry;
import org.onosproject.incubator.net.tunnel.TunnelProviderService;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.incubator.net.tunnel.TunnelStore;
import org.onosproject.incubator.net.tunnel.TunnelStoreDelegate;
import org.onosproject.incubator.net.tunnel.TunnelSubscription;
import org.onosproject.net.Annotations;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
import org.onosproject.net.Path;
import org.onosproject.net.provider.AbstractProviderService;
import org.onosproject.net.provider.ProviderId;
import org.slf4j.Logger;

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

import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Provides implementation of the tunnel NB/SB APIs.
 */
@Component(immediate = true, enabled = true)
@Service
public class TunnelManager
        extends AbstractListenerProviderRegistry<TunnelEvent, TunnelListener,
                                                 TunnelProvider, TunnelProviderService>
        implements TunnelService, TunnelAdminService, TunnelProviderRegistry {

    private static final String TUNNNEL_ID_NULL = "Tunnel ID cannot be null";
    private static final String TUNNNEL_NULL = "Tunnel cannot be null";

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

    private final TunnelStoreDelegate delegate = new InternalStoreDelegate();

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected TunnelStore store;


    @Activate
    public void activate() {
        store.setDelegate(delegate);
        eventDispatcher.addSink(TunnelEvent.class, listenerRegistry);
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        store.unsetDelegate(delegate);
        eventDispatcher.removeSink(TunnelEvent.class);
        log.info("Stopped");
    }

    @Override
    public void removeTunnel(TunnelId tunnelId) {
        checkNotNull(tunnelId, TUNNNEL_ID_NULL);
        Tunnel tunnel = store.queryTunnel(tunnelId);
        if (tunnel != null) {
            store.deleteTunnel(tunnelId);
            if (tunnel.providerId() != null) {
                TunnelProvider provider = getProvider(tunnel.providerId());
                if (provider != null) {
                    provider.releaseTunnel(tunnel);
                }
            } else {
                Set<ProviderId> ids = getProviders();
                for (ProviderId providerId : ids) {
                    TunnelProvider provider = getProvider(providerId);
                    provider.releaseTunnel(tunnel);
                }
            }
        }
    }

    @Override
    public void updateTunnel(Tunnel tunnel, Path path) {
        store.createOrUpdateTunnel(tunnel);
        if (tunnel.providerId() != null) {
            TunnelProvider provider = getProvider(tunnel.providerId());
            if (provider != null) {
                provider.updateTunnel(tunnel, path);
            }
        } else {
            Set<ProviderId> ids = getProviders();
            for (ProviderId providerId : ids) {
                TunnelProvider provider = getProvider(providerId);
                provider.updateTunnel(tunnel, path);
            }
        }
    }

    @Override
    public void updateTunnelState(Tunnel tunnel, State state) {
        Tunnel storedTunnel = store.queryTunnel(tunnel.tunnelId());
        store.createOrUpdateTunnel(storedTunnel, state);
    }

    @Override
    public void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst,
                              ProviderId producerName) {
        Collection<Tunnel> setTunnels = store.queryTunnel(src, dst);
        if (!setTunnels.isEmpty()) {
            store.deleteTunnel(src, dst, producerName);
            for (Tunnel tunnel : setTunnels) {
                if (producerName != null
                        && !tunnel.providerId().equals(producerName)) {
                    continue;
                }
                if (tunnel.providerId() != null) {
                    TunnelProvider provider = getProvider(tunnel.providerId());
                    if (provider != null) {
                        provider.releaseTunnel(tunnel);
                    }
                } else {
                    Set<ProviderId> ids = getProviders();
                    for (ProviderId providerId : ids) {
                        TunnelProvider provider = getProvider(providerId);
                        provider.releaseTunnel(tunnel);
                    }
                }
            }
        }
    }

    @Override
    public void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst, Type type,
                              ProviderId producerName) {
        Collection<Tunnel> setTunnels = store.queryTunnel(src, dst);
        if (!setTunnels.isEmpty()) {
            store.deleteTunnel(src, dst, type, producerName);
            for (Tunnel tunnel : setTunnels) {
                if (producerName != null
                        && !tunnel.providerId().equals(producerName)
                        || !type.equals(tunnel.type())) {
                    continue;
                }
                if (tunnel.providerId() != null) {
                    TunnelProvider provider = getProvider(tunnel.providerId());
                    if (provider != null) {
                        provider.releaseTunnel(tunnel);
                    }
                } else {
                    Set<ProviderId> ids = getProviders();
                    for (ProviderId providerId : ids) {
                        TunnelProvider provider = getProvider(providerId);
                        provider.releaseTunnel(tunnel);
                    }
                }
            }
        }
    }

    @Override
    public Tunnel borrowTunnel(ApplicationId consumerId, TunnelId tunnelId,
                                  Annotations... annotations) {
        return store.borrowTunnel(consumerId, tunnelId, annotations);
    }

    @Override
    public Collection<Tunnel> borrowTunnel(ApplicationId consumerId,
                                              TunnelName tunnelName,
                                              Annotations... annotations) {
        return store.borrowTunnel(consumerId, tunnelName, annotations);
    }

    @Override
    public Collection<Tunnel> borrowTunnel(ApplicationId consumerId,
                                              TunnelEndPoint src, TunnelEndPoint dst,
                                              Annotations... annotations) {
        Collection<Tunnel> tunnels = store.borrowTunnel(consumerId, src,
                                                           dst, annotations);
        if (tunnels == null || tunnels.size() == 0) {
            Tunnel tunnel = new DefaultTunnel(null, src, dst, null, null, null,
                                              null, null, annotations);
            Set<ProviderId> ids = getProviders();
            for (ProviderId providerId : ids) {
                TunnelProvider provider = getProvider(providerId);
                provider.setupTunnel(tunnel, null);
            }
        }
        return tunnels;
    }

    @Override
    public Collection<Tunnel> borrowTunnel(ApplicationId consumerId,
                                              TunnelEndPoint src, TunnelEndPoint dst,
                                              Type type, Annotations... annotations) {
        Collection<Tunnel> tunnels = store.borrowTunnel(consumerId, src,
                                                           dst, type,
                                                           annotations);
        if (tunnels == null || tunnels.size() == 0) {
            Tunnel tunnel = new DefaultTunnel(null, src, dst, type, null, null,
                                              null, null, annotations);
            Set<ProviderId> ids = getProviders();
            for (ProviderId providerId : ids) {
                TunnelProvider provider = getProvider(providerId);
                provider.setupTunnel(tunnel, null);
            }
        }
        return tunnels;
    }

    @Override
    public TunnelId setupTunnel(ApplicationId producerId, ElementId srcElementId, Tunnel tunnel, Path path) {
        // TODO: producerId to check if really required to consider while setup the tunnel.
        checkNotNull(tunnel, TUNNNEL_NULL);
        TunnelId tunnelId = store.createOrUpdateTunnel(tunnel, State.INIT);
        if (tunnelId != null) {
            Set<ProviderId> ids = getProviders();
            Tunnel newT = queryTunnel(tunnelId);
            for (ProviderId providerId : ids) {
                TunnelProvider provider = getProvider(providerId);
                provider.setupTunnel(srcElementId, newT, path);
            }
        }
        return tunnelId;
    }

    @Override
    public boolean downTunnel(ApplicationId producerId, TunnelId tunnelId) {
        // TODO: producerId to check if really required to consider while deleting the tunnel.
        checkNotNull(tunnelId, TUNNNEL_ID_NULL);
        Tunnel tunnel = store.queryTunnel(tunnelId);
        if (tunnel != null) {
            TunnelId updtTunnelId = store.createOrUpdateTunnel(tunnel, State.INACTIVE);
            if (updtTunnelId != null) {
                Set<ProviderId> ids = getProviders();
                for (ProviderId providerId : ids) {
                    TunnelProvider provider = getProvider(providerId);
                    provider.releaseTunnel(tunnel);
                }
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean returnTunnel(ApplicationId consumerId,
                                     TunnelId tunnelId, Annotations... annotations) {
        return store.returnTunnel(consumerId, tunnelId, annotations);
    }

    @Override
    public boolean returnTunnel(ApplicationId consumerId,
                                     TunnelName tunnelName,
                                     Annotations... annotations) {
        return store.returnTunnel(consumerId, tunnelName, annotations);
    }

    @Override
    public boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src,
                                     TunnelEndPoint dst, Type type,
                                     Annotations... annotations) {
        return store.returnTunnel(consumerId, src, dst, type, annotations);
    }

    @Override
    public boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src,
                                     TunnelEndPoint dst, Annotations... annotations) {
        return store.returnTunnel(consumerId, src, dst, annotations);
    }

    @Override
    public Tunnel queryTunnel(TunnelId tunnelId) {
        return store.queryTunnel(tunnelId);
    }

    @Override
    public Collection<TunnelSubscription> queryTunnelSubscription(ApplicationId consumerId) {
        return store.queryTunnelSubscription(consumerId);
    }

    @Override
    public Collection<Tunnel> queryTunnel(Type type) {
        return store.queryTunnel(type);
    }

    @Override
    public Collection<Tunnel> queryTunnel(TunnelEndPoint src, TunnelEndPoint dst) {
        return store.queryTunnel(src, dst);
    }


    @Override
    public Collection<Tunnel> queryAllTunnels() {
        return store.queryAllTunnels();
    }

    @Override
    public int tunnelCount() {
        return store.tunnelCount();
    }

    @Override
    protected TunnelProviderService createProviderService(TunnelProvider provider) {
        return new InternalTunnelProviderService(provider);
    }

    private class InternalTunnelProviderService
            extends AbstractProviderService<TunnelProvider>
            implements TunnelProviderService {
        protected InternalTunnelProviderService(TunnelProvider provider) {
            super(provider);
        }


        @Override
        public TunnelId tunnelAdded(TunnelDescription tunnel) {
            Tunnel storedTunnel = new DefaultTunnel(provider().id(),
                                                    tunnel.src(), tunnel.dst(),
                                                    tunnel.type(),
                                                    tunnel.groupId(),
                                                    tunnel.id(),
                                                    tunnel.tunnelName(),
                                                    tunnel.path(),
                                                    tunnel.resource(),
                                                    tunnel.annotations());
            return store.createOrUpdateTunnel(storedTunnel);
        }

        @Override
        public TunnelId tunnelAdded(TunnelDescription tunnel, State state) {
            Tunnel storedTunnel = new DefaultTunnel(provider().id(),
                                                    tunnel.src(), tunnel.dst(),
                                                    tunnel.type(),
                                                    state,
                                                    tunnel.groupId(),
                                                    tunnel.id(),
                                                    tunnel.tunnelName(),
                                                    tunnel.path(),
                                                    tunnel.resource(),
                                                    tunnel.annotations());
            return store.createOrUpdateTunnel(storedTunnel);
        }

        @Override
        public void tunnelUpdated(TunnelDescription tunnel) {
            Tunnel storedTunnel = new DefaultTunnel(provider().id(),
                                                    tunnel.src(), tunnel.dst(),
                                                    tunnel.type(),
                                                    tunnel.groupId(),
                                                    tunnel.id(),
                                                    tunnel.tunnelName(),
                                                    tunnel.path(),
                                                    tunnel.resource(),
                                                    tunnel.annotations());
            store.createOrUpdateTunnel(storedTunnel);
        }

        @Override
        public void tunnelUpdated(TunnelDescription tunnel, State state) {
            Tunnel storedTunnel = new DefaultTunnel(provider().id(),
                                                    tunnel.src(), tunnel.dst(),
                                                    tunnel.type(),
                                                    state,
                                                    tunnel.groupId(),
                                                    tunnel.id(),
                                                    tunnel.tunnelName(),
                                                    tunnel.path(),
                                                    tunnel.resource(),
                                                    tunnel.annotations());
            store.createOrUpdateTunnel(storedTunnel, state);
        }

        @Override
        public void tunnelRemoved(TunnelDescription tunnel) {
            if (tunnel.id() != null) {
                store.deleteTunnel(tunnel.id());
                return;
            }
            if (tunnel.src() != null && tunnel.dst() != null
                    && tunnel.type() != null) {
                store.deleteTunnel(tunnel.src(), tunnel.dst(), tunnel.type(),
                                   provider().id());
                return;
            }
            if (tunnel.src() != null && tunnel.dst() != null
                    && tunnel.type() == null) {
                store.deleteTunnel(tunnel.src(), tunnel.dst(), provider().id());
                return;
            }
        }


        @Override
        public Tunnel tunnelQueryById(TunnelId tunnelId) {
            return store.queryTunnel(tunnelId);
        }


    }

    private class InternalStoreDelegate implements TunnelStoreDelegate {
        @Override
        public void notify(TunnelEvent event) {
            if (event != null) {
                post(event);
            }
        }
    }

    @Override
    public Iterable<Tunnel> getTunnels(DeviceId deviceId) {
        return Collections.emptyList();
    }

}
