/*
 * Copyright 2014 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.onlab.onos.oecfg;

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 java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * Utility program to convert standard ONOS config JSON to format expected
 * by the OE Link switch.
 */
public final class OELinkConfig {

    private ObjectMapper mapper = new ObjectMapper();
    private Map<String, String> dpidToName = new HashMap<>();

    public static void main(String[] args) {
        try {
            OELinkConfig config = new OELinkConfig();
            JsonNode json = config.convert(System.in);
            System.out.println(json.toString());
        } catch (IOException e) {
            System.err.println("Unable to convert JSON due to: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private OELinkConfig() {
    }

    private JsonNode convert(InputStream input) throws IOException {
        JsonNode json = mapper.readTree(input);
        ObjectNode result = mapper.createObjectNode();
        result.set("opticalSwitches", opticalSwitches(json));
        result.set("opticalLinks", opticalLinks(json));
        return result;
    }

    private JsonNode opticalSwitches(JsonNode json) {
        ArrayNode result = mapper.createArrayNode();
        for (JsonNode node : json.get("devices")) {
            String dpid = dpid(node.path("uri"));
            String name = node.path("name").asText("none");
            dpidToName.put(dpid, name);
            if (node.path("type").asText("none").equals("ROADM")) {
                result.add(opticalSwitch(dpid, name, (ObjectNode) node));
            }
        }
        return result;
    }

    private ObjectNode opticalSwitch(String dpid, String name, ObjectNode node) {
        ObjectNode result = mapper.createObjectNode();
        ObjectNode annot = (ObjectNode) node.path("annotations");
        result.put("allowed", true).put("type", "Roadm")
                .put("name", name).put("nodeDpid", dpid)
                .put("latitude", annot.path("latitude").asDouble(0.0))
                .put("longitude", annot.path("longitude").asDouble(0.0))
                .set("params", switchParams(annot));
        return result;
    }

    private ObjectNode switchParams(ObjectNode annot) {
        return mapper.createObjectNode()
                .put("numRegen", annot.path("optical.regens").asInt(0));
    }

    private JsonNode opticalLinks(JsonNode json) {
        ArrayNode result = mapper.createArrayNode();
        for (JsonNode node : json.get("links")) {
            if (node.path("type").asText("none").equals("OPTICAL")) {
                result.add(opticalLink((ObjectNode) node));
            }
        }
        return result;
    }

    private ObjectNode opticalLink(ObjectNode node) {
        ObjectNode result = mapper.createObjectNode();
        ObjectNode annot = (ObjectNode) node.path("annotations");
        String src = dpid(node.path("src"));
        String dst = dpid(node.path("dst"));
        result.put("allowed", true).put("type", linkType(annot))
                .put("nodeDpid1", src).put("nodeDpid2", dst)
                .set("params", linkParams(src, dst, node, annot));
        return result;
    }

    private String linkType(ObjectNode annot) {
        return annot.path("optical.type").asText("cross-connect").equals("WDM") ?
                "wdmLink" : "pktOptLink";
    }

    private ObjectNode linkParams(String src, String dst,
                                  ObjectNode node, ObjectNode annot) {
        ObjectNode result = mapper.createObjectNode()
                .put("nodeName1", dpidToName.get(src))
                .put("nodeName2", dpidToName.get(dst))
                .put("port1", port(node.path("src")))
                .put("port2", port(node.path("dst")));
        if (annot.has("bandwidth")) {
            result.put("bandwidth", annot.path("bandwidth").asInt());
        }
        if (annot.has("optical.waves")) {
            result.put("numWaves", annot.path("optical.waves").asInt());
        }
        return result;
    }

    private String dpid(JsonNode node) {
        String s = node.asText("of:0000000000000000").substring(3);
        return s.substring(0, 2) + ":" + s.substring(2, 4) + ":" +
                s.substring(4, 6) + ":" + s.substring(6, 8) + ":" +
                s.substring(8, 10) + ":" + s.substring(10, 12) + ":" +
                s.substring(12, 14) + ":" + s.substring(14, 16);
    }

    private int port(JsonNode node) {
        return Integer.parseInt(node.asText("of:0000000000000000/0").substring(20));
    }

}
