/*
 * Copyright 2018-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.openstacktelemetry.codec;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.TpPort;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.net.DeviceId;
import org.onosproject.openstacktelemetry.api.FlowInfo;
import org.onosproject.openstacktelemetry.api.StatsInfo;
import org.onosproject.openstacktelemetry.impl.DefaultFlowInfo;
import org.slf4j.Logger;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Openstack telemetry codec used for serializing and de-serializing JSON string.
 */
public final class FlowInfoJsonCodec extends JsonCodec<FlowInfo> {

    private final Logger log = getLogger(getClass());

    private static final String FLOW_TYPE = "flowType";
    private static final String DEVICE_ID = "deviceId";
    private static final String INPUT_INTERFACE_ID = "inputInterfaceId";
    private static final String OUTPUT_INTERFACE_ID = "outputInterfaceId";

    private static final String VLAN_ID = "vlanId";
    private static final String VXLAN_ID = "vxlanId";
    private static final String SRC_IP = "srcIp";
    private static final String SRC_IP_PREFIX_LEN = "srcIpPrefixLength";
    private static final String DST_IP = "dstIp";
    private static final String DST_IP_PREFIX_LEN = "dstIpPrefixLength";
    private static final String SRC_PORT = "srcPort";
    private static final String DST_PORT = "dstPort";
    private static final String PROTOCOL = "protocol";
    private static final String SRC_MAC = "srcMac";
    private static final String DST_MAC = "dstMac";
    private static final String STATS_INFO = "statsInfo";

    @Override
    public ObjectNode encode(FlowInfo info, CodecContext context) {
        checkNotNull(info, "FlowInfo cannot be null");

        ObjectNode result = context.mapper().createObjectNode()
                .put(FLOW_TYPE, info.flowType())
                .put(DEVICE_ID, info.deviceId().toString())
                .put(INPUT_INTERFACE_ID, info.inputInterfaceId())
                .put(OUTPUT_INTERFACE_ID, info.outputInterfaceId())
                .put(SRC_IP, info.srcIp().address().toString())
                .put(SRC_IP_PREFIX_LEN, info.srcIp().prefixLength())
                .put(DST_IP, info.dstIp().address().toString())
                .put(DST_IP_PREFIX_LEN, info.dstIp().prefixLength())
                .put(SRC_PORT, info.srcPort().toString())
                .put(DST_PORT, info.dstPort().toString())
                .put(PROTOCOL, info.protocol())
                .put(SRC_MAC, info.srcMac().toString())
                .put(DST_MAC, info.dstMac().toString());


        if (info.vlanId() != null) {
            result.put(VLAN_ID, info.vlanId().toString());
        } else {
            result.put(VXLAN_ID, info.vxlanId());
        }

        ObjectNode statsInfoJson =
                context.codec(StatsInfo.class).encode(info.statsInfo(), context);

        result.put(STATS_INFO, statsInfoJson);

        return result;
    }

    @Override
    public FlowInfo decode(ObjectNode json, CodecContext context) {
        if (json == null || !json.isObject()) {
            return null;
        }

        String flowType = json.get(FLOW_TYPE).asText();
        String deviceId = json.get(DEVICE_ID).asText();
        int inputInterfaceId = json.get(INPUT_INTERFACE_ID).asInt();
        int outputInterfaceId = json.get(OUTPUT_INTERFACE_ID).asInt();
        String srcIp = json.get(SRC_IP).asText();
        int srcIpPrefixLength = json.get(SRC_IP_PREFIX_LEN).asInt();
        String dstIp = json.get(DST_IP).asText();
        int dstIpPrefixLength = json.get(DST_IP_PREFIX_LEN).asInt();
        int srcPort = json.get(SRC_PORT).asInt();
        int dstPort = json.get(DST_PORT).asInt();
        String protocol = json.get(PROTOCOL).asText();
        String srcMac = json.get(SRC_MAC).asText();
        String dstMac = json.get(DST_MAC).asText();

        JsonNode statsInfoJson = json.get(STATS_INFO);

        JsonCodec<StatsInfo> statsInfoCodec = context.codec(StatsInfo.class);
        StatsInfo statsInfo = statsInfoCodec.decode((ObjectNode) statsInfoJson.deepCopy(), context);

        return new DefaultFlowInfo.DefaultBuilder()
                .withFlowType(Byte.valueOf(flowType))
                .withDeviceId(DeviceId.deviceId(deviceId))
                .withInputInterfaceId(inputInterfaceId)
                .withOutputInterfaceId(outputInterfaceId)
                .withSrcIp(IpPrefix.valueOf(IpAddress.valueOf(srcIp), srcIpPrefixLength))
                .withDstIp(IpPrefix.valueOf(IpAddress.valueOf(dstIp), dstIpPrefixLength))
                .withSrcPort(TpPort.tpPort(srcPort))
                .withDstPort(TpPort.tpPort(dstPort))
                .withProtocol(Byte.valueOf(protocol))
                .withSrcMac(MacAddress.valueOf(srcMac))
                .withDstMac(MacAddress.valueOf(dstMac))
                .withStatsInfo(statsInfo)
                .build();
    }
}
