/*
 * 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.net.intent.impl.compiler;

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.onlab.osgi.DefaultServiceDirectory;
import org.onlab.osgi.ServiceDirectory;
import org.onosproject.core.ApplicationId;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.virtual.NetworkId;
import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
import org.onosproject.incubator.net.virtual.VirtualNetworkService;
import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
import org.onosproject.incubator.net.virtual.VirtualPort;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.FilteredConnectPoint;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentCompilationException;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.PointToPointIntent;
import org.onosproject.net.topology.TopologyService;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * An intent compiler for {@link org.onosproject.incubator.net.virtual.VirtualNetworkIntent}.
 */
@Component(immediate = true)
public class VirtualNetworkIntentCompiler
        extends ConnectivityIntentCompiler<VirtualNetworkIntent> {

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

    private static final String NETWORK_ID = "networkId=";
    protected static final String KEY_FORMAT = "{" + NETWORK_ID + "%s, src=%s, dst=%s}";

    protected ServiceDirectory serviceDirectory = new DefaultServiceDirectory();

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected VirtualNetworkService manager;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected IntentService intentService;

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


    @Activate
    public void activate() {
        intentManager.registerCompiler(VirtualNetworkIntent.class, this);
    }

    @Deactivate
    public void deactivate() {
        intentManager.unregisterCompiler(VirtualNetworkIntent.class);
    }

    @Override
    public List<Intent> compile(VirtualNetworkIntent intent, List<Intent> installable) {

        log.debug("Compiling intent: " + intent);
        List<Intent> intents = new ArrayList<>();
        Optional<Path> path = getPaths(intent).stream()
                .findFirst();
        if (path != null && path.isPresent()) {
            List<Link> links = path.get().links();

            // First create an intent between the intent ingress CP and the first link source CP,
            // only if the two CPs are not the same.
            Link firstLink = links.get(0);
            if (!intent.ingressPoint().equals(firstLink.src())) {
                intents.add(createPtPtIntent(intent, intent.ingressPoint(), firstLink.src()));
            }

            // Next create an intent between the intent egress CP and the last link destination CP,
            // only if the two CPs are not the same.
            Link lastLink = links.get(links.size() - 1);
            if (!intent.egressPoint().equals(lastLink.dst())) {
                intents.add(createPtPtIntent(intent, lastLink.dst(), intent.egressPoint()));
            }

            // Now loop through all of the virtual links in the path and create an intent.
            // An intent is also created connecting two virtual links.
            final int[] index = {0};
            links.forEach(link -> {
                intents.add(createPtPtIntent(intent, link.src(), link.dst()));
                if (index[0] > 0) {
                    Link previousLink = links.get(index[0] - 1);
                    intents.add(createPtPtIntent(intent, previousLink.dst(), link.src()));
                }
                index[0]++;
            });
        } else {
            throw new IntentCompilationException("Unable to find a path for intent " + intent);
        }

        return intents;
    }

    /**
     * Returns the paths for the virtual network intent.
     *
     * @param intent virtual network intent
     * @return set of paths
     */
    private Set<Path> getPaths(VirtualNetworkIntent intent) {

        TopologyService topologyService = manager.get(intent.networkId(), TopologyService.class);
        if (topologyService == null) {
            throw new IntentCompilationException("topologyService is null");
        }
        return topologyService.getPaths(topologyService.currentTopology(),
                                        intent.ingressPoint().deviceId(), intent.egressPoint().deviceId());
    }

    /**
     * Encodes the key using the network identifier, application identifier, source and destination
     * connect points.
     *
     * @param networkId     virtual network identifier
     * @param applicationId application identifier
     * @param src           source connect point
     * @param dst           destination connect point
     * @return encoded key
     */

    private static Key encodeKey(NetworkId networkId, ApplicationId applicationId, ConnectPoint src, ConnectPoint dst) {
        String key = String.format(KEY_FORMAT, networkId, src, dst);
        return Key.of(key, applicationId);
    }

    /**
     * Creates a point-to-point intent using the virtual network intent between the source and destination
     * connect point.
     *
     * @param intent virtual network intent
     * @param src    source connect point
     * @param dst    destination connect point
     * @return point to point intent
     */
    private Intent createPtPtIntent(VirtualNetworkIntent intent, ConnectPoint src, ConnectPoint dst) {
        ConnectPoint ingressPoint = mapVirtualToPhysicalPort(intent.networkId(), src);
        ConnectPoint egressPoint = mapVirtualToPhysicalPort(intent.networkId(), dst);
        Key intentKey = encodeKey(intent.networkId(), intent.appId(), ingressPoint, egressPoint);

        // TODO Currently there can only be one intent between the ingress and egress across
        // all virtual networks. We may want to support multiple intents between the same src/dst pairs.
        PointToPointIntent physicalIntent = PointToPointIntent.builder()
                .key(intentKey)
                .appId(intent.appId())
                .filteredIngressPoint(new FilteredConnectPoint(ingressPoint))
                .filteredEgressPoint(new FilteredConnectPoint(egressPoint))
                .constraints(intent.constraints())
                .selector(intent.selector())
                .treatment(intent.treatment())
                .resourceGroup(intent.resourceGroup())
                .build();
        log.debug("Submitting physical intent: " + physicalIntent);
        intentService.submit(physicalIntent);

        // Store the physical intent against this virtual intent.
        store.addTunnelId(intent, TunnelId.valueOf(physicalIntent.key().toString()));

        return physicalIntent;
    }

    /**
     * Maps the virtual connect point to a physical connect point.
     *
     * @param networkId virtual network identifier
     * @param virtualCp virtual connect point
     * @return physical connect point
     */
    private ConnectPoint mapVirtualToPhysicalPort(NetworkId networkId, ConnectPoint virtualCp) {
        Set<VirtualPort> ports = manager.getVirtualPorts(networkId, virtualCp.deviceId());
        for (VirtualPort port : ports) {
            if (port.element().id().equals(virtualCp.elementId()) &&
                    port.number().equals(virtualCp.port())) {
                return new ConnectPoint(port.realizedBy().deviceId(), port.realizedBy().port());
            }
        }
        return null;
    }
}

