/*
 * 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.tetunnel.impl;

import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.GroupId;
import org.onosproject.incubator.net.tunnel.DefaultTunnel;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelAdminService;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelName;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DeviceId;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.tetopology.management.api.TeTopology;
import org.onosproject.tetopology.management.api.TeTopologyKey;
import org.onosproject.tetopology.management.api.TeTopologyService;
import org.onosproject.tetunnel.api.TeTunnelAdminService;
import org.onosproject.tetunnel.api.TeTunnelProviderService;
import org.onosproject.tetunnel.api.TeTunnelService;
import org.onosproject.tetunnel.api.TeTunnelStore;
import org.onosproject.tetunnel.api.lsp.TeLsp;
import org.onosproject.tetunnel.api.lsp.TeLspKey;
import org.onosproject.tetunnel.api.tunnel.TeTunnel;
import org.onosproject.tetunnel.api.tunnel.TeTunnelEndpoint;
import org.onosproject.tetunnel.api.tunnel.TeTunnelKey;
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.List;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Implementation of TE tunnel attributes management service.
 */
@Component(immediate = true, service = { TeTunnelService.class, TeTunnelAdminService.class,
        TeTunnelProviderService.class })
public class TeTunnelManager implements TeTunnelService, TeTunnelAdminService,
        TeTunnelProviderService {

    private static final String TE_TUNNEL_APP = "onos-app-tetunnel";

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

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected TeTunnelStore store;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected TunnelService tunnelService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected TunnelAdminService tunnelAdminService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected TeTopologyService teTopologyService;

    private ApplicationId appId;

    @Activate
    public void activate() {
        appId = coreService.registerApplication(TE_TUNNEL_APP);

        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        log.info("Stopped");
    }

    @Override
    public TunnelId createTeTunnel(TeTunnel teTunnel) {
        if (!store.addTeTunnel(teTunnel)) {
            log.error("can not add teTunnel: {}", teTunnel);
            return null;
        }

        TunnelId tunnelId = TunnelId.valueOf(teTunnel.teTunnelKey().toString());
        Tunnel tunnel = new DefaultTunnel(ProviderId.NONE,
                                          new TeTunnelEndpoint(teTunnel.srcNode(),
                                                               teTunnel.srcTp()),
                                          new TeTunnelEndpoint(teTunnel.dstNode(),
                                                               teTunnel.dstTp()),
                                          Tunnel.Type.MPLS, new GroupId(0),
                                          tunnelId,
                                          TunnelName.tunnelName(teTunnel.name()),
                                          null,
                                          DefaultAnnotations.builder().build());
        store.setTunnelId(teTunnel.teTunnelKey(), tunnelId);
        TeTopology srcTopology = teTopologyService.teTopology(
                teTopologyService.teNode(teTunnel.srcNode())
                .underlayTeTopologyId());
        if (srcTopology == null) {
            srcTopology = teTopologyService.teTopology(teTunnel.srcNode()
                                                               .teTopologyKey());
        }
        DeviceId domainId = srcTopology.ownerId();
        TunnelId id = tunnelService.setupTunnel(appId, domainId, tunnel, null);
        if (id == null) {
            log.error("can not create tunnel for te {}",
                      teTunnel.teTunnelKey());
            store.removeTeTunnel(teTunnel.teTunnelKey());
            return null;
        }
        if (!id.equals(tunnelId)) {
            //this should not happen
            log.error("tunnelId changed, oldId:{}, newId:{}", tunnelId, id);
            store.setTunnelId(teTunnel.teTunnelKey(), id);
        }
        return id;
    }

    @Override
    public void setTunnelId(TeTunnelKey teTunnelKey, TunnelId tunnelId) {
        store.setTunnelId(teTunnelKey, tunnelId);
    }

    @Override
    public void updateTeTunnel(TeTunnel teTunnel) {
        //TODO: updateTeTunnel
    }

    @Override
    public void updateTunnelState(TeTunnelKey key, Tunnel.State state) {
        tunnelAdminService.updateTunnelState(
                tunnelService.queryTunnel(getTunnelId(key)), state);
    }

    @Override
    public TeLspKey teLspAdded(TeLsp lsp) {
        if (store.addTeLsp(lsp)) {
            return lsp.teLspKey();
        }

        return null;
    }

    @Override
    public void teLspRemoved(TeLsp lsp) {
        store.removeTeLsp(lsp.teLspKey());
    }

    @Override
    public void updateTeLsp(TeLsp lsp) {
        store.updateTeLsp(lsp);
    }

    @Override
    public void removeTeTunnel(TeTunnelKey teTunnelKey) {
        tunnelAdminService.updateTunnelState(
                tunnelService.queryTunnel(getTunnelId(teTunnelKey)),
                Tunnel.State.REMOVING);
        List<TeTunnelKey> segmentTunnels =
                getTeTunnel(teTunnelKey).segmentTunnels();
        if (segmentTunnels == null || segmentTunnels.isEmpty()) {
            // this is a single domain tunnel, removes it right away
            tunnelAdminService.removeTunnel(getTunnelId(teTunnelKey));
        }
    }

    @Override
    public void setSegmentTunnel(TeTunnelKey e2eTunnelKey,
                                 List<TeTunnelKey> segmentTunnels) {
        TeTunnel e2eTunnel = store.getTeTunnel(e2eTunnelKey);
        if (e2eTunnel == null) {
            log.error("unknown e2eTunnelKey: {}", e2eTunnelKey);
            return;
        }
        e2eTunnel.segmentTunnels(segmentTunnels);

        for (TeTunnelKey key : segmentTunnels) {
            TeTunnel segmentTunnel = store.getTeTunnel(key);
            if (segmentTunnel == null) {
                log.warn("unknown segmentTunnel: {}", key);
                continue;
            }
            segmentTunnel.e2eTunnelKey(e2eTunnelKey);
        }
    }

    @Override
    public TeTunnel getTeTunnel(TeTunnelKey key) {
        return store.getTeTunnel(key);
    }

    @Override
    public TeTunnel getTeTunnel(TunnelId id) {
        return store.getTeTunnel(id);
    }

    @Override
    public TunnelId getTunnelId(TeTunnelKey key) {
        return store.getTunnelId(key);
    }

    @Override
    public Collection<TeTunnel> getTeTunnels() {
        return store.getTeTunnels();
    }

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

    @Override
    public Collection<TeTunnel> getTeTunnels(TeTopologyKey key) {
        return store.getTeTunnels(key);
    }

    @Override
    public TeLsp getTeLsp(TeLspKey key) {
        return store.getTeLsp(key);
    }

    @Override
    public Collection<TeLsp> getTeLsps() {
        return store.getTeLsps();
    }

    @Override
    public TunnelId teTunnelAdded(TeTunnel teTunnel) {
        //TODO teTunnelAdded
        return null;
    }

    @Override
    public void teTunnelRemoved(TeTunnel teTunnel) {
        TeTunnelKey e2eTunnelKey = teTunnel.e2eTunnelKey();
        store.removeTeTunnel(teTunnel.teTunnelKey());

        // it's a segment tunnel
        if (e2eTunnelKey != null) {
            boolean finished = true;
            for (TeTunnelKey key : getTeTunnel(e2eTunnelKey).segmentTunnels()) {
                if (getTeTunnel(key) != null) {
                    // FIXME need a better way to determine whether a segment tunnel is removed.
                    finished = false;
                }
            }
            if (finished) {
                // all segment tunnels are removed
                tunnelAdminService.removeTunnel(getTunnelId(e2eTunnelKey));
                store.removeTeTunnel(e2eTunnelKey);
            }
        }
    }
}
