/*
 * Copyright 2015-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.ui.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.rest.BaseResource;
import org.slf4j.Logger;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import static org.onlab.util.Tools.readTreeFromStream;
import static org.slf4j.LoggerFactory.getLogger;

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

    private static final String ID = "id";
    private static final String URI = "uri";

    // length of a MAC defined as a string ... "xx:xx:xx:xx:xx:xx"
    private static final int MAC_LEN = 17;
    private static final char SLASH_CHAR = '/';

    private static final Logger log = getLogger(TopologyResource.class);

    private final ObjectMapper mapper = new ObjectMapper();

    /**
     * Returns the location data associated with devices and hosts, that is
     * currently cached in the Meta-UI store.
     *
     * @return cached location data for devices and hosts
     */
    @Path("geoloc")
    @GET
    @Produces("application/json")
    public Response getGeoLocations() {
        ObjectNode rootNode = mapper.createObjectNode();
        ArrayNode devices = mapper.createArrayNode();
        ArrayNode hosts = mapper.createArrayNode();

        Map<String, ObjectNode> metaUi = TopologyViewMessageHandler.getMetaUi();
        for (String id : metaUi.keySet()) {
            ObjectNode memento = metaUi.get(id);
            if (isHostId(id)) {
                addGeoData(hosts, ID, id, memento);
            } else {
                addGeoData(devices, URI, id, memento);
            }
        }

        rootNode.set("devices", devices);
        rootNode.set("hosts", hosts);
        return Response.ok(rootNode.toString()).build();
    }

    private boolean isHostId(String id) {
        return id.length() > MAC_LEN && id.charAt(MAC_LEN) == SLASH_CHAR;
    }

    private void addGeoData(ArrayNode array, String idField, String id,
                            ObjectNode memento) {
        ObjectNode node = mapper.createObjectNode().put(idField, id);
        ObjectNode annot = mapper.createObjectNode();
        node.set("annotations", annot);

        // TODO: add handling of gridY/gridX if locType is "grid" (not "geo")

        try {
            annot.put("latitude", memento.get("latOrY").asDouble())
                 .put("longitude", memento.get("longOrX").asDouble());
            array.add(node);
        } catch (Exception e) {
            log.debug("Skipping geo entry");
        }
    }

    /**
     * Stores sprite data for retrieval by the UI Topology View.
     *
     * @param stream input data stream (typically from an uploaded file).
     * @return REST response
     * @throws IOException if there is an issue reading from the stream
     * @deprecated since Junco (1.9), in favor of client-side defined sprite layers
     */
    @Path("sprites")
    @POST
    @Consumes("application/json")
    @Deprecated
    public Response setSprites(InputStream stream) throws IOException {
        JsonNode root = readTreeFromStream(mapper, stream);
        String name = root.path("defn_name").asText("sprites");
        get(SpriteService.class).put(name, root);
        return Response.ok().build();
    }
}
