/*
 * Copyright 2017-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.opencord.sadis.impl;

import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.packet.VlanId;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.opencord.sadis.UniTagInformation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UniTagInformationCodec extends JsonCodec<UniTagInformation> {

    private final Logger log = LoggerFactory.getLogger(this.getClass());


    private static final String UNI_TAG_MATCH = "uniTagMatch";
    private static final String PON_CTAG = "ponCTag";
    private static final String PON_STAG = "ponSTag";
    private static final String US_PON_CTAG_PCP = "usPonCTagPriority";
    private static final String US_PON_STAG_PCP = "usPonSTagPriority";
    private static final String DS_PON_CTAG_PCP = "dsPonCTagPriority";
    private static final String DS_PON_STAG_PCP = "dsPonSTagPriority";
    private static final String TP_ID = "technologyProfileId";
    private static final String US_BP = "upstreamBandwidthProfile";
    private static final String DS_BP = "downstreamBandwidthProfile";
    private static final String US_OLT_BP = "upstreamOltBandwidthProfile";
    private static final String DS_OLT_BP = "downstreamOltBandwidthProfile";
    private static final String SN = "serviceName";
    private static final String MAC_LEARN = "enableMacLearning";
    private static final String MAC = "configuredMacAddress";
    private static final String DHCP_REQ = "isDhcpRequired";
    private static final String IGMP_REQ = "isIgmpRequired";
    private static final String PPPOE_REQ = "isPppoeRequired";
    private static final int NO_PCP = -1;
    private static final int NO_TP = -1;
    private static final String EMPTY_BP = "";
    private static final String EMPTY_SN = "";
    private static final boolean DEFAULT_MAC_LEARN = false;
    private static final String EMPTY_MAC = "";
    private static final boolean DEFAULT_DHCP_REQ = false;
    private static final boolean DEFAULT_IGMP_REQ = false;
    private static final boolean DEFAULT_PPPOE_REQ = false;

    @Override
    public ObjectNode encode(UniTagInformation entry, CodecContext context) {
        return context.mapper().createObjectNode()
                .put(UNI_TAG_MATCH, entry.getUniTagMatch().toShort())
                .put(PON_CTAG, entry.getPonCTag().toShort())
                .put(PON_STAG, entry.getPonSTag().toShort())
                .put(US_PON_CTAG_PCP, entry.getUsPonCTagPriority())
                .put(US_PON_STAG_PCP, entry.getUsPonSTagPriority())
                .put(DS_PON_CTAG_PCP, entry.getDsPonCTagPriority())
                .put(DS_PON_STAG_PCP, entry.getDsPonSTagPriority())
                .put(TP_ID, entry.getTechnologyProfileId())
                .put(US_BP, entry.getUpstreamBandwidthProfile())
                .put(DS_BP, entry.getDownstreamBandwidthProfile())
                .put(US_OLT_BP, entry.getUpstreamOltBandwidthProfile())
                .put(DS_OLT_BP, entry.getDownstreamOltBandwidthProfile())
                .put(SN, entry.getServiceName())
                .put(MAC_LEARN, entry.getEnableMacLearning())
                .put(MAC, entry.getConfiguredMacAddress())
                .put(DHCP_REQ, entry.getIsDhcpRequired())
                .put(IGMP_REQ, entry.getIsIgmpRequired())
                .put(PPPOE_REQ, entry.getIsPppoeRequired());
    }

    @Override
    public UniTagInformation decode(ObjectNode json, CodecContext context) {
        if (json == null || !json.isObject()) {
            return null;
        }
        UniTagInformation.Builder tagInfoBuilder = new UniTagInformation.Builder();
        String usBp = json.get(US_BP) == null ? EMPTY_BP :
                json.get(US_BP).asText();
        String dsBp = json.get(DS_BP) == null ? EMPTY_BP :
                json.get(DS_BP).asText();
        String usOltBp = json.get(US_OLT_BP) == null ? usBp : json.get(US_OLT_BP).asText();
        String dsOltBp = json.get(DS_OLT_BP) == null ? dsBp : json.get(DS_OLT_BP).asText();
        tagInfoBuilder.setUniTagMatch(json.get(UNI_TAG_MATCH) == null ? VlanId.vlanId(VlanId.NO_VID) :
                VlanId.vlanId(json.get(UNI_TAG_MATCH).shortValue()))
                .setPonCTag(json.get(PON_CTAG) == null ? VlanId.vlanId(VlanId.NO_VID) :
                        VlanId.vlanId(json.get(PON_CTAG).shortValue()))
                .setPonSTag(json.get(PON_STAG) == null ? VlanId.vlanId(VlanId.NO_VID) :
                        VlanId.vlanId(json.get(PON_STAG).shortValue()))
                .setUsPonCTagPriority(json.get(US_PON_CTAG_PCP) == null ? NO_PCP :
                        json.get(US_PON_CTAG_PCP).asInt())
                .setUsPonSTagPriority(json.get(US_PON_STAG_PCP) == null ? NO_PCP :
                        json.get(US_PON_STAG_PCP).asInt())
                .setDsPonCTagPriority(json.get(DS_PON_CTAG_PCP) == null ? NO_PCP :
                        json.get(DS_PON_CTAG_PCP).asInt())
                .setDsPonSTagPriority(json.get(DS_PON_STAG_PCP) == null ? NO_PCP :
                        json.get(DS_PON_STAG_PCP).asInt())
                .setTechnologyProfileId(json.get(TP_ID) == null ? NO_TP :
                        json.get(TP_ID).asInt())
                .setUpstreamBandwidthProfile(usBp)
                .setDownstreamBandwidthProfile(dsBp)
                .setUpstreamOltBandwidthProfile(usOltBp)
                .setDownstreamOltBandwidthProfile(dsOltBp)
                .setServiceName(json.get(SN) == null ? EMPTY_SN :
                        json.get(SN).asText())
                .setEnableMacLearning(json.get(MAC_LEARN) == null ? DEFAULT_MAC_LEARN :
                        json.get(MAC_LEARN).asBoolean())
                .setConfiguredMacAddress(json.get(MAC) == null ? EMPTY_MAC :
                        json.get(MAC).asText())
                .setIsDhcpRequired(json.get(DHCP_REQ) == null ? DEFAULT_DHCP_REQ :
                        json.get(DHCP_REQ).asBoolean())
                .setIsIgmpRequired(json.get(IGMP_REQ) == null ? DEFAULT_IGMP_REQ :
                        json.get(IGMP_REQ).asBoolean())
                .setIsPppoeRequired(json.get(PPPOE_REQ) == null ? DEFAULT_PPPOE_REQ :
                        json.get(PPPOE_REQ).asBoolean());
        log.info("Codec UniTagInformation Codec builder returning {}", tagInfoBuilder.build());
        return tagInfoBuilder.build();
    }
}
