/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.onlab.onos.tvue;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.ElementId;
import org.onlab.onos.net.Host;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.Path;
import org.onlab.onos.net.device.DeviceService;
import org.onlab.onos.net.host.HostService;
import org.onlab.onos.net.link.LinkService;
import org.onlab.onos.net.topology.PathService;
import org.onlab.onos.net.topology.Topology;
import org.onlab.onos.net.topology.TopologyGraph;
import org.onlab.onos.net.topology.TopologyService;
import org.onlab.onos.net.topology.TopologyVertex;
import org.onlab.packet.IpPrefix;
import org.onlab.rest.BaseResource;

import javax.ws.rs.GET;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import static org.onlab.onos.net.DeviceId.deviceId;
import static org.onlab.onos.net.HostId.hostId;
import static org.onlab.onos.net.PortNumber.portNumber;

/**
 * Topology viewer resource.
 */
@javax.ws.rs.Path("topology")
public class TopologyResource extends BaseResource {

    @javax.ws.rs.Path("/graph")
    @GET
    @Produces("application/json")
    public Response graph() {
        ObjectMapper mapper = new ObjectMapper();

        // Fetch the services we'll be using.
        DeviceService deviceService = get(DeviceService.class);
        HostService hostService = get(HostService.class);
        TopologyService topologyService = get(TopologyService.class);

        // Fetch the current topology and its graph that we'll use to render.
        Topology topo = topologyService.currentTopology();
        TopologyGraph graph = topologyService.getGraph(topo);

        // Build all interior vertexes, i.e. no end-station hosts yet
        ArrayNode vertexesNode = mapper.createArrayNode();
        for (TopologyVertex vertex : graph.getVertexes()) {
            vertexesNode.add(json(mapper, vertex.deviceId(), 2,
                                  vertex.deviceId().uri().getSchemeSpecificPart(),
                                  deviceService.isAvailable(vertex.deviceId())));
        }

        // Now scan all links and count number of them between the same devices
        // using a normalized link key.
        Map<String, AggLink> linkRecords = aggregateLinks();

        // Now build all interior edges using the aggregated links.
        ArrayNode edgesNode = mapper.createArrayNode();
        for (AggLink lr : linkRecords.values()) {
            edgesNode.add(json(mapper, lr.links.size(), lr.link.src(), lr.link.dst()));
        }

        // Merge the exterior and interior vertexes and inject host links as
        // the exterior edges.
        for (Host host : hostService.getHosts()) {
            Set<IpPrefix> ipAddresses = host.ipAddresses();
            IpPrefix ipAddress = ipAddresses.isEmpty() ? null : ipAddresses.iterator().next();
            String label = ipAddress != null ? ipAddress.toString() : host.mac().toString();
            vertexesNode.add(json(mapper, host.id(), 3, label, true));
            edgesNode.add(json(mapper, 1, host.location(), new ConnectPoint(host.id(), portNumber(-1))));
        }

        // Now put the vertexes and edges into a root node and ship them off
        ObjectNode rootNode = mapper.createObjectNode();
        rootNode.set("vertexes", vertexesNode);
        rootNode.set("edges", edgesNode);
        return Response.ok(rootNode.toString()).build();
    }


    /**
     * Returns a JSON array of all paths between the specified hosts.
     *
     * @param src source host id
     * @param dst target host id
     * @return JSON array of paths
     */
    @javax.ws.rs.Path("/paths/{src}/{dst}")
    @GET
    @Produces("application/json")
    public Response paths(@PathParam("src") String src, @PathParam("dst") String dst) {
        ObjectMapper mapper = new ObjectMapper();
        PathService pathService = get(PathService.class);
        Set<Path> paths = pathService.getPaths(elementId(src), elementId(dst));

        ArrayNode pathsNode = mapper.createArrayNode();
        for (Path path : paths) {
            pathsNode.add(json(mapper, path));
        }

        // Now put the vertexes and edges into a root node and ship them off
        ObjectNode rootNode = mapper.createObjectNode();
        rootNode.set("paths", pathsNode);
        return Response.ok(rootNode.toString()).build();
    }

    // Creates either device ID or host ID as appropriate.
    private ElementId elementId(String id) {
        return id.startsWith("nic:") ? hostId(id) : deviceId(id);
    }

    // Scan all links and counts number of them between the same devices
    // using a normalized link key.
    private Map<String, AggLink> aggregateLinks() {
        Map<String, AggLink> aggLinks = new HashMap<>();
        LinkService linkService = get(LinkService.class);
        for (Link link : linkService.getLinks()) {
            String key = key(link);
            AggLink lr = aggLinks.get(key);
            if (lr == null) {
                lr = new AggLink(key);
                aggLinks.put(key, lr);
            }
            lr.addLink(link);
        }
        return aggLinks;
    }

    // Produces JSON for a graph vertex.
    private ObjectNode json(ObjectMapper mapper, ElementId id, int group,
                            String label, boolean isOnline) {
        return mapper.createObjectNode()
                .put("name", id.toString())
                .put("label", label)
                .put("group", group)
                .put("online", isOnline);
    }

    // Produces JSON for a graph edge.
    private ObjectNode json(ObjectMapper mapper, int count,
                            ConnectPoint src, ConnectPoint dst) {
        return json(mapper, count, id(src), id(dst));
    }

    // Produces JSON for a graph edge.
    private ObjectNode json(ObjectMapper mapper, int count, String src, String dst) {
        return mapper.createObjectNode()
                .put("source", src).put("target", dst).put("value", count);
    }

    // Produces JSON representation of a network path.
    private ArrayNode json(ObjectMapper mapper, Path path) {
        ArrayNode pathNode = mapper.createArrayNode();
        for (Link link : path.links()) {
            ObjectNode linkNode = mapper.createObjectNode()
                    .put("src", id(link.src()))
                    .put("dst", id(link.dst()));
            pathNode.add(linkNode);
        }
        return pathNode;
    }


    // Aggregate link of all links between the same devices regardless of
    // their direction.
    private class AggLink {
        Link link; // representative links

        final String key;
        final Set<Link> links = new HashSet<>();

        AggLink(String key) {
            this.key = key;
        }

        void addLink(Link link) {
            links.add(link);
            if (this.link == null) {
                this.link = link;
            }
        }
    }

    // Returns a canonical key for the specified link.
    static String key(Link link) {
        String s = id(link.src());
        String d = id(link.dst());
        return s.compareTo(d) > 0 ? d + s : s + d;
    }

    // Returns a formatted string for the element associated with the given
    // connection point.
    private static String id(ConnectPoint cp) {
        return cp.elementId().toString();
    }

}
