/*
 * 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.node.ObjectNode;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.onlab.packet.TpPort;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.openstacktelemetry.api.StatsFlowRule;
import org.onosproject.openstacktelemetry.impl.DefaultStatsFlowRule;
import org.slf4j.Logger;

import org.onlab.packet.IpPrefix;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.openstacktelemetry.util.OpenstackTelemetryUtil.getProtocolTypeFromString;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * JSON codec for StatsFlowRule.
 */
public class StatsFlowRuleJsonCodec extends JsonCodec<StatsFlowRule> {

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

    public static final String SRC_IP_PREFIX = "srcIpPrefix";
    public static final String DST_IP_PREFIX = "dstIpPrefix";
    public static final String IP_PROTOCOL   = "ipProtocol";
    public static final String SRC_TP_PORT   = "srcTpPort";
    public static final String DST_TP_PORT   = "dstTpPort";

    public ObjectNode encode(StatsFlowRule flowRule, CodecContext context) {
        checkNotNull(flowRule, "FlowInfo cannot be null");
        ObjectNode result = context.mapper().createObjectNode()
                            .put(SRC_IP_PREFIX, flowRule.srcIpPrefix().toString())
                            .put(DST_IP_PREFIX, flowRule.dstIpPrefix().toString())
                            .put(IP_PROTOCOL, flowRule.ipProtocol())
                            .put(SRC_TP_PORT, flowRule.srcTpPort().toString())
                            .put(DST_TP_PORT, flowRule.dstTpPort().toString());
        return result;
    }

    @Override
    public StatsFlowRule decode(ObjectNode json, CodecContext context) {
        if (json == null || !json.isObject()) {
            return null;
        }
        try {
            String srcIpPrefix = json.get(SRC_IP_PREFIX).asText();
            String dstIpPrefix = json.get(DST_IP_PREFIX).asText();

            DefaultStatsFlowRule.Builder flowRuleBuilder;

            if (json.get(IP_PROTOCOL) == null) {
                log.info("ipProtocol: null");
                flowRuleBuilder = DefaultStatsFlowRule.builder()
                        .srcIpPrefix(IpPrefix.valueOf(srcIpPrefix))
                        .dstIpPrefix(IpPrefix.valueOf(dstIpPrefix));
            } else {
                byte ipProtocol = getProtocolTypeFromString(json.get(IP_PROTOCOL).asText());
                int srcTpPort = json.get(SRC_TP_PORT).asInt();
                int dstTpPort = json.get(DST_TP_PORT).asInt();

                flowRuleBuilder = DefaultStatsFlowRule.builder()
                                    .srcIpPrefix(IpPrefix.valueOf(srcIpPrefix))
                                    .dstIpPrefix(IpPrefix.valueOf(dstIpPrefix))
                                    .ipProtocol(ipProtocol)
                                    .srcTpPort(TpPort.tpPort(srcTpPort))
                                    .dstTpPort(TpPort.tpPort(dstTpPort));
            }
            return flowRuleBuilder.build();
        } catch (Exception ex) {
            log.error("Exception Stack:\n{}", ExceptionUtils.getStackTrace(ex));
        }
        return null;
    }
}
