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

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import static org.onosproject.ui.JsonUtils.envelope;

/**
 * JSON utilities for the Topology View.
 */
public final class TopoJson {
    // package-private for unit test access
    static final String SHOW_HIGHLIGHTS = "showHighlights";

    static final String DEVICES = "devices";
    static final String HOSTS = "hosts";
    static final String LINKS = "links";
    static final String SUBDUE = "subdue";

    static final String ID = "id";
    static final String LABEL = "label";
    static final String CSS = "css";
    static final String BADGE = "badge";
    static final String STATUS = "status";
    static final String TXT = "txt";
    static final String GID = "gid";
    static final String MSG = "msg";

    static final String TITLE = "title";
    static final String TYPE = "type";
    static final String PROP_ORDER = "propOrder";
    static final String PROPS = "props";
    static final String BUTTONS = "buttons";


    private static final ObjectMapper MAPPER = new ObjectMapper();

    private static ObjectNode objectNode() {
        return MAPPER.createObjectNode();
    }

    private static ArrayNode arrayNode() {
        return MAPPER.createArrayNode();
    }

    // non-instantiable
    private TopoJson() { }

    /**
     * Returns a formatted message ready to send to the topology view
     * to render highlights.
     *
     * @param highlights highlights model to transform
     * @return fully formatted "show highlights" message
     */
    public static ObjectNode highlightsMessage(Highlights highlights) {
        return envelope(SHOW_HIGHLIGHTS, json(highlights));
    }

    /**
     * Transforms the given highlights model into a JSON message payload.
     *
     * @param highlights the model to transform
     * @return JSON payload
     */
    public static ObjectNode json(Highlights highlights) {
        ObjectNode payload = objectNode();

        ArrayNode devices = arrayNode();
        ArrayNode hosts = arrayNode();
        ArrayNode links = arrayNode();

        payload.set(DEVICES, devices);
        payload.set(HOSTS, hosts);
        payload.set(LINKS, links);

        highlights.devices().forEach(dh -> devices.add(json(dh)));
        highlights.hosts().forEach(hh -> hosts.add(json(hh)));
        highlights.links().forEach(lh -> links.add(json(lh)));

        Highlights.Amount toSubdue = highlights.subdueLevel();
        if (!toSubdue.equals(Highlights.Amount.ZERO)) {
            payload.put(SUBDUE, toSubdue.toString());
        }
        return payload;
    }

    private static ObjectNode json(NodeBadge b) {
        ObjectNode n = objectNode()
                .put(STATUS, b.status().code())
                .put(b.isGlyph() ? GID : TXT, b.text());
        if (b.message() != null) {
            n.put(MSG, b.message());
        }
        return n;
    }

    private static ObjectNode json(DeviceHighlight dh) {
        ObjectNode n = objectNode()
                .put(ID, dh.elementId());
        if (dh.subdued()) {
            n.put(SUBDUE, true);
        }
        NodeBadge badge = dh.badge();
        if (badge != null) {
            n.set(BADGE, json(badge));
        }
        return n;
    }

    private static ObjectNode json(HostHighlight hh) {
        ObjectNode n = objectNode()
                .put(ID, hh.elementId());
        if (hh.subdued()) {
            n.put(SUBDUE, true);
        }
        NodeBadge badge = hh.badge();
        if (badge != null) {
            n.set(BADGE, json(badge));
        }
        return n;
    }

    private static ObjectNode json(LinkHighlight lh) {
        ObjectNode n = objectNode()
                .put(ID, lh.elementId())
                .put(LABEL, lh.label())
                .put(CSS, lh.cssClasses());
        if (lh.subdued()) {
            n.put(SUBDUE, true);
        }
        return n;
    }

    /**
     * Translates the given property panel into JSON, for returning
     * to the client.
     *
     * @param pp the property panel model
     * @return JSON payload
     */
    public static ObjectNode json(PropertyPanel pp) {
        ObjectNode result = objectNode()
                .put(TITLE, pp.title())
                .put(TYPE, pp.typeId())
                .put(ID, pp.id());

        ObjectNode pnode = objectNode();
        ArrayNode porder = arrayNode();
        for (PropertyPanel.Prop p : pp.properties()) {
            porder.add(p.key());
            pnode.put(p.key(), p.value());
        }
        result.set(PROP_ORDER, porder);
        result.set(PROPS, pnode);

        ArrayNode buttons = arrayNode();
        for (ButtonId b : pp.buttons()) {
            buttons.add(b.id());
        }
        result.set(BUTTONS, buttons);
        return result;
    }

}
