/*
 * 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.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 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);
        store.deleteTunnel(tunnelId);
        Tunnel tunnel = store.queryTunnel(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 removeTunnels(TunnelEndPoint src, TunnelEndPoint dst,
                              ProviderId producerName) {
        store.deleteTunnel(src, dst, producerName);
        Collection<Tunnel> setTunnels = store.queryTunnel(src, dst);
        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) {
        store.deleteTunnel(src, dst, type, producerName);
        Collection<Tunnel> setTunnels = store.queryTunnel(src, dst);
        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 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.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.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.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.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();
    }

}
