/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.onrc.onos.core.datagrid.web;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;

import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.core.intent.ConstrainedShortestPathIntent;
import net.onrc.onos.core.intent.Intent;
import net.onrc.onos.core.intent.IntentMap;
import net.onrc.onos.core.intent.IntentOperation;
import net.onrc.onos.core.intent.IntentOperationList;
import net.onrc.onos.core.intent.ShortestPathIntent;
import net.onrc.onos.core.intent.runtime.IPathCalcRuntimeService;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author nickkaranatsios
 */
public class IntentResource extends ServerResource {
    private final static Logger log = LoggerFactory.getLogger(IntentResource.class);
    // TODO need to assign proper application id.
    private final String APPLN_ID = "1";

    @Post("json")
    public String store(String jsonIntent) throws IOException {
        IPathCalcRuntimeService pathRuntime = (IPathCalcRuntimeService) getContext()
                .getAttributes().get(IPathCalcRuntimeService.class.getCanonicalName());
        if (pathRuntime == null) {
            log.warn("Failed to get path calc runtime");
            return "";
        }
        String reply = "";
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jNode = null;
        try {
            jNode = mapper.readValue(jsonIntent, JsonNode.class);
        } catch (JsonGenerationException ex) {
            log.error("JsonGeneration exception ", ex);
        } catch (JsonMappingException ex) {
            log.error("JsonMappingException occurred", ex);
        } catch (IOException ex) {
            log.error("IOException occurred", ex);
        }

        if (jNode != null) {
            reply = parseJsonNode(jNode.getElements(), pathRuntime);
        }
        return reply;
    }

    @Delete("json")
    public String store() {
        IPathCalcRuntimeService pathRuntime = (IPathCalcRuntimeService) getContext().
                getAttributes().get(IPathCalcRuntimeService.class.getCanonicalName());
        pathRuntime.purgeIntents();
        // TODO no reply yet from the purge intents call
        return "";

    }

    @Get("json")
    public String retrieve() throws IOException {
        IPathCalcRuntimeService pathRuntime = (IPathCalcRuntimeService) getContext().
                getAttributes().get(IPathCalcRuntimeService.class.getCanonicalName());

        String intentCategory = (String) getRequestAttributes().get("category");
        IntentMap intentMap = null;
        if (intentCategory.equals("high")) {
            intentMap = pathRuntime.getHighLevelIntents();
        } else {
            intentMap = pathRuntime.getPathIntents();
        }
        ObjectMapper mapper = new ObjectMapper();
        String restStr = "";

        String intentId = (String) getRequestAttributes().get("intent_id");
        ArrayNode arrayNode = mapper.createArrayNode();
        Collection<Intent> intents = intentMap.getAllIntents();
        if (!intents.isEmpty()) {
            if ((intentId != null)) {
                String applnIntentId = APPLN_ID + ":" + intentId;
                Intent intent = intentMap.getIntent(applnIntentId);
                if (intent != null) {
                    ObjectNode node = mapper.createObjectNode();
                    // TODO refactor/remove duplicate code.
                    node.put("intent_id", intentId);
                    node.put("status", intent.getState().toString());
                    LinkedList<String> logs = intent.getLogs();
                    ArrayNode logNode = mapper.createArrayNode();
                    for (String intentLog : logs) {
                        logNode.add(intentLog);
                    }
                    node.put("log", logNode);
                    arrayNode.add(node);
                }
            } else {
                for (Intent intent : intents) {
                    ObjectNode node = mapper.createObjectNode();
                    String applnIntentId = intent.getId();
                    intentId = applnIntentId.split(":")[1];
                    node.put("intent_id", intentId);
                    node.put("status", intent.getState().toString());
                    LinkedList<String> logs = intent.getLogs();
                    ArrayNode logNode = mapper.createArrayNode();
                    for (String intentLog : logs) {
                        logNode.add(intentLog);
                    }
                    node.put("log", logNode);
                    arrayNode.add(node);
                }
            }
            restStr = mapper.writeValueAsString(arrayNode);
        }
        return restStr;
    }

    private String parseJsonNode(Iterator<JsonNode> nodes,
                                 IPathCalcRuntimeService pathRuntime) throws IOException {
        IntentOperationList operations = new IntentOperationList();
        ObjectMapper mapper = new ObjectMapper();
        ArrayNode arrayNode = mapper.createArrayNode();
        while (nodes.hasNext()) {
            JsonNode node = nodes.next();
            if (node.isObject()) {
                JsonNode data;
                Iterator<String> fieldNames = node.getFieldNames();
                Map<String, Object> fields = new HashMap<>();
                while (fieldNames.hasNext()) {
                    String fieldName = fieldNames.next();
                    data = node.get(fieldName);
                    parseFields(data, fieldName, fields);
                }
                Intent intent = processIntent(fields, operations);
                appendIntentStatus(intent, (String) fields.get("intent_id"), mapper, arrayNode);
            }
        }
        pathRuntime.executeIntentOperations(operations);
        return mapper.writeValueAsString(arrayNode);
    }

    private void appendIntentStatus(Intent intent, final String intentId,
                                    ObjectMapper mapper, ArrayNode arrayNode) throws IOException {
        ObjectNode node = mapper.createObjectNode();
        node.put("intent_id", intentId);
        node.put("status", intent.getState().toString());
        LinkedList<String> logs = intent.getLogs();
        ArrayNode logNode = mapper.createArrayNode();
        for (String intentLog : logs) {
            logNode.add(intentLog);
        }
        node.put("log", logNode);
        arrayNode.add(node);
    }

    private Intent processIntent(Map<String, Object> fields, IntentOperationList operations) {
        String intentType = (String) fields.get("intent_type");
        String intentOp = (String) fields.get("intent_op");
        Intent intent;
        String intentId = (String) fields.get("intent_id");
        boolean pathFrozen = false;
        if (intentId.startsWith("F")) { // TODO define REST API for frozen intents
            pathFrozen = true;
            intentId = intentId.substring(1);
        }
        String applnIntentId = APPLN_ID + ":" + intentId;

        IntentOperation.Operator operation = IntentOperation.Operator.ADD;
        if ((intentOp.equals("remove"))) {
            operation = IntentOperation.Operator.REMOVE;
        }
        if (intentType.equals("shortest_intent_type")) {
            ShortestPathIntent spi = new ShortestPathIntent(applnIntentId,
                    Long.decode((String) fields.get("srcSwitch")),
                    (long) fields.get("srcPort"),
                    MACAddress.valueOf((String) fields.get("srcMac")).toLong(),
                    Long.decode((String) fields.get("dstSwitch")),
                    (long) fields.get("dstPort"),
                    MACAddress.valueOf((String) fields.get("dstMac")).toLong());
            spi.setPathFrozen(pathFrozen);
            operations.add(operation, spi);
            intent = spi;
        } else {
            ConstrainedShortestPathIntent cspi = new ConstrainedShortestPathIntent(applnIntentId,
                    Long.decode((String) fields.get("srcSwitch")),
                    (long) fields.get("srcPort"),
                    MACAddress.valueOf((String) fields.get("srcMac")).toLong(),
                    Long.decode((String) fields.get("dstSwitch")),
                    (long) fields.get("dstPort"),
                    MACAddress.valueOf((String) fields.get("dstMac")).toLong(),
                    (double) fields.get("bandwidth"));
            cspi.setPathFrozen(pathFrozen);
            operations.add(operation, cspi);
            intent = cspi;
        }
        return intent;
    }

    private void parseFields(JsonNode node, String fieldName, Map<String, Object> fields) {
        if ((node.isTextual())) {
            fields.put(fieldName, node.getTextValue());
        } else if ((node.isInt())) {
            fields.put(fieldName, (long) node.getIntValue());
        } else if (node.isDouble()) {
            fields.put(fieldName, node.getDoubleValue());
        } else if ((node.isLong())) {
            fields.put(fieldName, node.getLongValue());
        }
    }
}
