/*
 * 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.segmentrouting.web;

import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.VlanId;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.net.ConnectPoint;
import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
import org.onosproject.segmentrouting.pwaas.L2Mode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.onosproject.segmentrouting.pwaas.PwaasUtil.*;

/**
 * Codec of PseudowireCodec class.
 */
public final class PseudowireCodec extends JsonCodec<DefaultL2TunnelDescription> {

    // JSON field names
    private static final String PW_ID = "pwId";
    private static final String CP1 = "cP1";
    private static final String CP2 = "cP2";
    private static final String CP1_INNER_TAG = "cP1InnerTag";
    private static final String CP1_OUTER_TAG = "cP1OuterTag";
    private static final String CP2_INNER_TAG = "cP2InnerTag";
    private static final String CP2_OUTER_TAG = "cP2OouterTag";
    private static final String MODE = "mode";
    private static final String SERVICE_DELIM_TAG = "serviceTag";
    private static final String PW_LABEL = "pwLabel";

    private static Logger log = LoggerFactory
            .getLogger(PseudowireCodec.class);

    @Override
    public ObjectNode encode(DefaultL2TunnelDescription pseudowire, CodecContext context) {
        final ObjectNode result = context.mapper().createObjectNode()
                .put(PW_ID, pseudowire.l2Tunnel().tunnelId());

        result.put(CP1, pseudowire.l2TunnelPolicy().cP1().toString());
        result.put(CP2, pseudowire.l2TunnelPolicy().cP2().toString());

        result.put(CP1_INNER_TAG, pseudowire.l2TunnelPolicy().cP1InnerTag().toString());
        result.put(CP1_OUTER_TAG, pseudowire.l2TunnelPolicy().cP1OuterTag().toString());


        result.put(CP2_INNER_TAG, pseudowire.l2TunnelPolicy().cP2InnerTag().toString());
        result.put(CP2_OUTER_TAG, pseudowire.l2TunnelPolicy().cP2OuterTag().toString());

        result.put(MODE, pseudowire.l2Tunnel().pwMode() == L2Mode.RAW ? "RAW" : "TAGGED");
        result.put(SERVICE_DELIM_TAG, pseudowire.l2Tunnel().sdTag().toString());
        result.put(PW_LABEL, pseudowire.l2Tunnel().pwLabel().toString());

        return result;
    }

    /**
     * Decodes a json containg a single field with the pseudowire id.
     *
     * @param json Json to decode.
     * @return The pseudowire id.
     */
    public static Integer decodeId(ObjectNode json) {

        Integer id = parsePwId(json.path(PW_ID).asText());
        if (id == null) {
            log.error("Pseudowire id is not an integer!");
            return null;
        }

        return id;
    }

    @Override
    public DefaultL2TunnelDescription decode(ObjectNode json, CodecContext context) {

        String tempString;

        Integer id = parsePwId(json.path(PW_ID).asText());
        if (id == null) {
            log.error("Pseudowire id is not an integer");
            return null;
        }

        ConnectPoint cP1, cP2;
        try {
            tempString = json.path(CP1).asText();
            cP1 = ConnectPoint.deviceConnectPoint(tempString);
        } catch (Exception e) {
            log.error("cP1 is not a valid connect point!");
            return null;
        }

        try {
            tempString = json.path(CP2).asText();
            cP2 = ConnectPoint.deviceConnectPoint(tempString);
        } catch (Exception e) {
            log.error("cP2 is not a valid connect point!");
            return null;
        }

        VlanId cP1InnerVlan = parseVlan(json.path(CP1_INNER_TAG).asText());
        VlanId cP1OuterVlan = parseVlan(json.path(CP1_OUTER_TAG).asText());
        VlanId cP2InnerVlan = parseVlan(json.path(CP2_INNER_TAG).asText());
        VlanId cP2OuterVlan = parseVlan(json.path(CP2_OUTER_TAG).asText());
        if ((cP1InnerVlan == null) || (cP1OuterVlan == null) ||
                (cP2InnerVlan == null) || (cP2OuterVlan == null)) {
            log.error("One or more vlan for cp1 or cp2 is malformed, it shouldbe an integer / Any / None / *");
            return null;
        }

        L2Mode mode = parseMode(json.path(MODE).asText());
        if (mode == null) {
            log.error("Mode should be RAW or TAGGED!");
            return null;
        }

        VlanId sdTag = parseVlan(json.path(SERVICE_DELIM_TAG).asText());
        if (sdTag == null) {
            log.error("SD tag is malformed, it should be an integer / Any / None / *");
            return null;
        }

        MplsLabel pwLabel = parsePWLabel(json.path(PW_LABEL).asText());
        if (pwLabel == null) {
            log.error("PW label is malformed, should be an integer!");
            return null;
        }

        DefaultL2Tunnel l2Tunnel;
        DefaultL2TunnelPolicy l2Policy;

        l2Tunnel = new DefaultL2Tunnel(mode, sdTag, id, pwLabel);
        l2Policy = new DefaultL2TunnelPolicy(id, cP1, cP1InnerVlan, cP1OuterVlan,
                                             cP2, cP2InnerVlan, cP2OuterVlan);

        return new DefaultL2TunnelDescription(l2Tunnel, l2Policy);

    }
}
