/*
 * Copyright 2016-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.driver.extensions;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;
import com.google.common.collect.Lists;
import com.google.common.primitives.Bytes;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onosproject.codec.CodecContext;
import org.onosproject.net.NshContextHeader;
import org.onosproject.net.NshServiceIndex;
import org.onosproject.net.NshServicePathId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
import org.onosproject.openflow.controller.ExtensionTreatmentInterpreter;
import org.projectfloodlight.openflow.protocol.OFActionType;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter;
import org.projectfloodlight.openflow.protocol.action.OFActionNicira;
import org.projectfloodlight.openflow.protocol.action.OFActionNiciraCt;
import org.projectfloodlight.openflow.protocol.action.OFActionNiciraMove;
import org.projectfloodlight.openflow.protocol.action.OFActionNiciraNat;
import org.projectfloodlight.openflow.protocol.action.OFActionNiciraResubmit;
import org.projectfloodlight.openflow.protocol.action.OFActionNiciraResubmitTable;
import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmEncapEthDst;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmEncapEthSrc;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmEncapEthType;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshC1;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshC2;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshC3;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshC4;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshMdtype;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshNp;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmNsi;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmNsp;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmTunGpeNp;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmTunnelIpv4Dst;
import org.projectfloodlight.openflow.types.IPv4Address;
import org.projectfloodlight.openflow.types.IPv6Address;
import org.projectfloodlight.openflow.types.MacAddress;
import org.projectfloodlight.openflow.types.U16;
import org.projectfloodlight.openflow.types.U32;
import org.projectfloodlight.openflow.types.U8;

import com.fasterxml.jackson.databind.node.ObjectNode;

import java.util.ArrayList;
import java.util.List;

/**
 * Interpreter for Nicira OpenFlow treatment extensions.
 */
public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviour
        implements ExtensionTreatmentInterpreter, ExtensionTreatmentResolver {

    private static final int TYPE_NICIRA = 0x2320;
    private static final int SRC_ARP_SHA = 0x00012206;
    private static final int SRC_ARP_SPA = 0x00002004;
    private static final int SRC_ETH = 0x00000406;
    private static final int SRC_IP = 0x00000e04;

    private static final int NSH_C1 = 0x0001e604;
    private static final int NSH_C2 = 0x0001e804;
    private static final int NSH_C3 = 0x0001ea04;
    private static final int NSH_C4 = 0x0001ec04;
    private static final int TUN_IPV4_DST = 0x00014004;
    private static final int TUN_ID = 0x12008;

    private static final int NAT_RANGE_IPV4_MIN = 0x01;
    private static final int NAT_RANGE_IPV4_MAX = 0x02;
    private static final int NAT_RANGE_IPV6_MIN = 0x04;
    private static final int NAT_RANGE_IPV6_MAX = 0x08;
    private static final int NAT_RANGE_PROTO_MIN = 0x10;
    private static final int NAT_RANGE_PROTO_MAX = 0x20;

    private static final int SUB_TYPE_RESUBMIT = 1;
    private static final int SUB_TYPE_RESUBMIT_TABLE = 14;
    private static final int SUB_TYPE_MOVE = 6;
    private static final int SUB_TYPE_CT = 35;
    private static final int SUB_TYPE_NAT = 36;
    private static final int SUB_TYPE_CT_CLEAR = 43;
    private static final int SUB_TYPE_PUSH_NSH = 38;
    private static final int SUB_TYPE_POP_NSH = 39;

    private static final String TUNNEL_DST = "tunnelDst";
    private static final String RESUBMIT = "resubmit";
    private static final String RESUBMIT_TABLE = "resubmitTable";
    private static final String NICIRA_NSH_SPI = "niciraNshSpi";
    private static final String NICIRA_NSH_SI = "niciraNshSi";
    private static final String NICIRA_NSH_CH = "niciraNshCh";
    private static final String NICIRA_MOVE = "niciraMove";

    private static final String TYPE = "type";

    private static final String MISSING_MEMBER_MESSAGE = " member is required in NiciraExtensionTreatmentInterpreter";

    @Override
    public boolean supported(ExtensionTreatmentType extensionTreatmentType) {
        if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SI.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH1.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH2.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH3.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT_TABLE.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SHA_TO_THA.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SPA_TO_TPA.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ETH_SRC_TO_DST.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_MDTYPE.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_NP.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_SRC.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_DST.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_TYPE
                .type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_PUSH_NSH.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_POP_NSH.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_TUN_GPE_NP.type())) {
            return true;
        }
        if (extensionTreatmentType
                .equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C1_TO_C1.type())) {
            return true;
        }
        if (extensionTreatmentType
                .equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_C2.type())) {
            return true;
        }
        if (extensionTreatmentType
                .equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C3_TO_C3.type())) {
            return true;
        }
        if (extensionTreatmentType
                .equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C4_TO_C4.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes
                                          .NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_ID_TO_TUN_ID
                .type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_TUN_ID
                                          .type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NAT.type())) {
            return true;
        }
        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT_CLEAR.type())) {
            return true;
        }
        return false;
    }

    @Override
    public OFAction mapInstruction(OFFactory factory, ExtensionTreatment extensionTreatment) {
        ExtensionTreatmentType type = extensionTreatment.type();
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type())) {
            NiciraSetTunnelDst tunnelDst = (NiciraSetTunnelDst) extensionTreatment;
            return factory.actions().setField(factory.oxms().tunnelIpv4Dst(
                    IPv4Address.of(tunnelDst.tunnelDst().toInt())));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT.type())) {
            NiciraResubmit resubmit = (NiciraResubmit) extensionTreatment;
            return factory.actions().niciraResubmit((int) resubmit.inPort().toLong(),
                                                  resubmit.table());
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT_TABLE.type())) {
            NiciraResubmitTable resubmitTable = (NiciraResubmitTable) extensionTreatment;
            return factory.actions().niciraResubmitTable((int) resubmitTable.inPort().toLong(),
                                                         resubmitTable.table());
        }

        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI.type())) {
            NiciraSetNshSpi niciraNshSpi = (NiciraSetNshSpi) extensionTreatment;
            return factory.actions().setField(factory.oxms().nsp(U32.of(niciraNshSpi.nshSpi().servicePathId())));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SI.type())) {
            NiciraSetNshSi niciraNshSi = (NiciraSetNshSi) extensionTreatment;
            return factory.actions().setField(factory.oxms().nsi(U8.of(niciraNshSi.nshSi().serviceIndex())));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH1.type())) {
            NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment;
            return factory.actions().setField(factory.oxms().nshC1(U32.of(niciraNshch.nshCh().nshContextHeader())));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH2.type())) {
            NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment;
            return factory.actions().setField(factory.oxms().nshC2(U32.of(niciraNshch.nshCh().nshContextHeader())));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH3.type())) {
            NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment;
            return factory.actions().setField(factory.oxms().nshC3(U32.of(niciraNshch.nshCh().nshContextHeader())));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4.type())) {
            NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment;
            return factory.actions().setField(factory.oxms().nshC4(U32.of(niciraNshch.nshCh().nshContextHeader())));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_MDTYPE.type())) {
            NiciraNshMdType niciraNshMdType = (NiciraNshMdType) extensionTreatment;
            return factory.actions().setField(factory.oxms().nshMdtype(U8.of(niciraNshMdType.nshMdType())));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_NP.type())) {
            NiciraNshNp niciraNshNp = (NiciraNshNp) extensionTreatment;
            return factory.actions().setField(factory.oxms().nshNp(U8.of(niciraNshNp.nshNp())));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_SRC.type())) {
            NiciraEncapEthSrc niciraEncapEthSrc = (NiciraEncapEthSrc) extensionTreatment;
            return factory.actions().setField(factory.oxms().encapEthSrc(MacAddress.of(niciraEncapEthSrc.encapEthSrc()
                    .toBytes())));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_DST.type())) {
            NiciraEncapEthDst niciraEncapEthDst = (NiciraEncapEthDst) extensionTreatment;
            return factory.actions().setField(factory.oxms().encapEthDst(MacAddress.of(niciraEncapEthDst.encapEthDst()
                    .toBytes())));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_TYPE.type())) {
            NiciraEncapEthType niciraEncapEthType = (NiciraEncapEthType) extensionTreatment;
            return factory.actions().setField(factory.oxms().encapEthType(U16.of(niciraEncapEthType.encapEthType())));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_PUSH_NSH.type())) {
            return factory.actions().niciraPushNsh();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_POP_NSH.type())) {
            return factory.actions().niciraPopNsh();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_TUN_GPE_NP.type())) {
            NiciraTunGpeNp niciraTunGpeNp = (NiciraTunGpeNp) extensionTreatment;
            return factory.actions().setField(factory.oxms().tunGpeNp(U8.of(niciraTunGpeNp.tunGpeNp())));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SHA_TO_THA.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SPA_TO_TPA.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ETH_SRC_TO_DST.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C1_TO_C1.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_C2.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C3_TO_C3.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C4_TO_C4.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST
                        .type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_ID_TO_TUN_ID.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_TUN_ID.type())) {
            MoveExtensionTreatment mov = (MoveExtensionTreatment) extensionTreatment;
            OFActionNiciraMove.Builder action = factory.actions()
                    .buildNiciraMove();
            action.setDstOfs(mov.dstOffset());
            action.setSrcOfs(mov.srcOffset());
            action.setNBits(mov.nBits());
            action.setSrc(mov.src());
            action.setDst(mov.dst());
            return action.build();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT.type())) {
            NiciraCt niciraCt = (NiciraCt) extensionTreatment;
            OFActionNiciraCt.Builder ctAction = factory.actions().buildNiciraCt();
            ctAction.setFlags(niciraCt.niciraCtFlags());
            ctAction.setZoneSrc(niciraCt.niciraCtZoneSrc());
            ctAction.setZone(niciraCt.niciraCtZone());
            ctAction.setRecircTable(niciraCt.niciraCtRecircTable());
            ctAction.setAlg(niciraCt.niciraCtAlg());

            for (ExtensionTreatment nestedTreatment : niciraCt.niciraCtNestActions()) {
                if (nestedTreatment instanceof NiciraNat) {
                    NiciraNat niciraNat = (NiciraNat) nestedTreatment;
                    OFActionNiciraNat.Builder action = factory.actions().buildNiciraNat();
                    action.setFlags(niciraNat.niciraNatFlags());

                    int presetFlags = niciraNat.niciraNatPresentFlags();
                    action.setRangePresent(presetFlags);

                    List<IPv4Address> ipv4RangeList = Lists.newArrayList();
                    List<IPv6Address> ipv6RangeList = Lists.newArrayList();
                    List<U16> portRangeList = Lists.newArrayList();
                    List<U8> padList = Lists.newArrayList();
                    if ((presetFlags & NAT_RANGE_IPV4_MIN) != 0) {
                        ipv4RangeList.add(IPv4Address.of(niciraNat.niciraNatIpAddressMin().getIp4Address().toString()));
                    }
                    if ((presetFlags & NAT_RANGE_IPV4_MAX) != 0) {
                        ipv4RangeList.add(IPv4Address.of(niciraNat.niciraNatIpAddressMax().getIp4Address().toString()));
                    }

                    if ((presetFlags & NAT_RANGE_IPV6_MIN) != 0) {
                        ipv6RangeList.add(IPv6Address.of(niciraNat.niciraNatIpAddressMin().getIp6Address().toString()));
                    }
                    if ((presetFlags & NAT_RANGE_IPV6_MAX) != 0) {
                        ipv6RangeList.add(IPv6Address.of(niciraNat.niciraNatIpAddressMax().getIp6Address().toString()));
                    }

                    if ((presetFlags & NAT_RANGE_PROTO_MIN) != 0) {
                        portRangeList.add(U16.of(niciraNat.niciraNatPortMin()));
                    }
                    if ((presetFlags & NAT_RANGE_PROTO_MAX) != 0) {
                        portRangeList.add(U16.of(niciraNat.niciraNatPortMax()));
                    }

                    for (; (ipv6RangeList.size() * 16 + ipv4RangeList.size() * 4
                            + portRangeList.size() * 2 + padList.size()) % 8 != 0;) {
                        padList.add(U8.ofRaw((byte) 0));
                    }

                    action.setIpv4Range(ipv4RangeList);
                    action.setIpv6Range(ipv6RangeList);
                    action.setPortRange(portRangeList);
                    action.setPad(padList);

                    //nat action must be nested in ct action
                    List<OFAction> actions = Lists.newArrayList();
                    actions.add(action.build());
                    ctAction.setActions(actions);
                }
            }
            return ctAction.build();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT_CLEAR.type())) {
            return factory.actions().niciraCtClear();
        }
        return null;
    }

    @Override
    public ExtensionTreatment mapAction(OFAction action) throws UnsupportedOperationException {
        if (action.getType().equals(OFActionType.SET_FIELD)) {
            OFActionSetField setFieldAction = (OFActionSetField) action;
            OFOxm<?> oxm = setFieldAction.getField();
            switch (oxm.getMatchField().id) {
            case TUNNEL_IPV4_DST:
                OFOxmTunnelIpv4Dst tunnelIpv4Dst = (OFOxmTunnelIpv4Dst) oxm;
                return new NiciraSetTunnelDst(Ip4Address.valueOf(tunnelIpv4Dst.getValue().getInt()));
            case NSP:
                OFOxmNsp nsp = (OFOxmNsp) oxm;
                return new NiciraSetNshSpi(NshServicePathId.of((nsp.getValue().getRaw())));
            case NSI:
                OFOxmNsi nsi = (OFOxmNsi) oxm;
                return new NiciraSetNshSi(NshServiceIndex.of((nsi.getValue().getRaw())));
            case NSH_C1:
                OFOxmNshC1 nshC1 = (OFOxmNshC1) oxm;
                return new NiciraSetNshContextHeader(NshContextHeader.of((nshC1.getValue().getRaw())),
                                                     ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH1
                                                     .type());
            case NSH_C2:
                OFOxmNshC2 nshC2 = (OFOxmNshC2) oxm;
                return new NiciraSetNshContextHeader(NshContextHeader.of((nshC2.getValue().getRaw())),
                                                     ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH2
                                                     .type());
            case NSH_C3:
                OFOxmNshC3 nshC3 = (OFOxmNshC3) oxm;
                return new NiciraSetNshContextHeader(NshContextHeader.of((nshC3.getValue().getRaw())),
                                                     ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH3
                                                     .type());
            case NSH_C4:
                OFOxmNshC4 nshC4 = (OFOxmNshC4) oxm;
                return new NiciraSetNshContextHeader(NshContextHeader.of((nshC4.getValue().getRaw())),
                                                     ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4
                                                     .type());
            case NSH_MDTYPE:
                OFOxmNshMdtype nshMdType = (OFOxmNshMdtype) oxm;
                return new NiciraNshMdType((nshMdType.getValue().getRaw()));
            case NSH_NP:
                OFOxmNshNp nshNp = (OFOxmNshNp) oxm;
                return new NiciraNshNp((nshNp.getValue().getRaw()));
            case ENCAP_ETH_SRC:
                OFOxmEncapEthSrc encapEthSrc = (OFOxmEncapEthSrc) oxm;
                return new NiciraEncapEthSrc(org.onlab.packet.MacAddress.valueOf((encapEthSrc.getValue().getBytes())));
            case ENCAP_ETH_DST:
                OFOxmEncapEthDst encapEthDst = (OFOxmEncapEthDst) oxm;
                return new NiciraEncapEthDst(org.onlab.packet.MacAddress.valueOf((encapEthDst.getValue().getBytes())));
            case ENCAP_ETH_TYPE:
                OFOxmEncapEthType encapEthType = (OFOxmEncapEthType) oxm;
                return new NiciraEncapEthType((encapEthType.getValue().getRaw()));
            case TUN_GPE_NP:
                OFOxmTunGpeNp tunGpeNp = (OFOxmTunGpeNp) oxm;
                return new NiciraTunGpeNp((tunGpeNp.getValue().getRaw()));
            default:
                throw new UnsupportedOperationException(
                        "Driver does not support extension type " + oxm.getMatchField().id);
            }
        }
        if (action.getType().equals(OFActionType.EXPERIMENTER)) {
            OFActionExperimenter experimenter = (OFActionExperimenter) action;
            if (Long.valueOf(experimenter.getExperimenter())
                    .intValue() == TYPE_NICIRA) {
                OFActionNicira nicira = (OFActionNicira) experimenter;
                switch (nicira.getSubtype()) {
                    case SUB_TYPE_MOVE:
                        OFActionNiciraMove moveAction = (OFActionNiciraMove) nicira;
                        switch (Long.valueOf(moveAction.getSrc()).intValue()) {
                            case SRC_ARP_SHA:
                                return NiciraMoveTreatmentFactory
                                        .createNiciraMovArpShaToTha();
                            case SRC_ETH:
                                return NiciraMoveTreatmentFactory
                                        .createNiciraMovEthSrcToDst();
                            case SRC_IP:
                                return NiciraMoveTreatmentFactory
                                        .createNiciraMovIpSrcToDst();
                            case SRC_ARP_SPA:
                                return NiciraMoveTreatmentFactory
                                        .createNiciraMovArpSpaToTpa();
                    case NSH_C1:
                        return NiciraMoveTreatmentFactory.createNiciraMovNshC1ToC1();
                    case NSH_C2:
                        if (Long.valueOf(moveAction.getDst()).intValue() == TUN_ID) {
                            return NiciraMoveTreatmentFactory.createNiciraMovNshC2ToTunId();
                        }
                        return NiciraMoveTreatmentFactory.createNiciraMovNshC2ToC2();
                    case NSH_C3:
                        return NiciraMoveTreatmentFactory.createNiciraMovNshC3ToC3();
                    case NSH_C4:
                        return NiciraMoveTreatmentFactory.createNiciraMovNshC4ToC4();
                    case TUN_IPV4_DST:
                        return NiciraMoveTreatmentFactory.createNiciraMovTunDstToTunDst();
                    case TUN_ID:
                        return NiciraMoveTreatmentFactory.createNiciraMovTunIdToTunId();
                            default:
                                throw new UnsupportedOperationException("Driver does not support move from "
                                + moveAction.getSrc() + " to " + moveAction.getDst() + "of length "
                                + moveAction.getNBits());
                        }
                    case SUB_TYPE_RESUBMIT:
                        OFActionNiciraResubmit resubmitAction = (OFActionNiciraResubmit) nicira;
                        return new NiciraResubmit(PortNumber.portNumber(resubmitAction.getInPort()));
                    case SUB_TYPE_PUSH_NSH:
                        return new NiciraPushNsh();
                    case SUB_TYPE_POP_NSH:
                        return new NiciraPopNsh();
                    case SUB_TYPE_RESUBMIT_TABLE:
                        OFActionNiciraResubmitTable resubmitTable = (OFActionNiciraResubmitTable) nicira;
                        return new NiciraResubmitTable(PortNumber.portNumber(resubmitTable.getInPort()),
                                                       resubmitTable.getTable());
                    case SUB_TYPE_CT:
                        OFActionNiciraCt ctAction = (OFActionNiciraCt) nicira;
                        List<OFAction> actions = ctAction.getActions();
                        for (OFAction act : actions) {
                            OFActionExperimenter ctExperimenter = (OFActionExperimenter) act;
                            if (Long.valueOf(ctExperimenter.getExperimenter()).intValue() == TYPE_NICIRA) {
                                OFActionNicira actionNicira = (OFActionNicira) ctExperimenter;
                                switch (actionNicira.getSubtype()) {
                                    case SUB_TYPE_NAT:
                                        OFActionNiciraNat natAction = (OFActionNiciraNat) actionNicira;
                                        int portMin = 0;
                                        int portMax = 0;
                                        IpAddress ipAddressMin = IpAddress.valueOf(0);
                                        IpAddress ipAddressMax = IpAddress.valueOf(0);
                                        //FIXME: we need to get ipv6 and port from list<ipv4> temporarily,
                                        // becase loxi don't know how to arrange these data to corresonding field.
                                        IPv4Address[] arrays = (IPv4Address[]) natAction
                                                .getIpv4Range().toArray(new IPv4Address[0]);
                                        int index = 0;
                                        if ((natAction.getRangePresent() & NAT_RANGE_IPV4_MIN) != 0) {
                                            ipAddressMin = IpAddress.valueOf(arrays[index++].toString());
                                        }
                                        if ((natAction.getRangePresent() & NAT_RANGE_IPV4_MAX) != 0) {
                                            ipAddressMax = IpAddress.valueOf(arrays[index++].toString());
                                        }
                                        if ((natAction.getRangePresent() & NAT_RANGE_IPV6_MIN) != 0) {
                                            byte[]  bytes = Bytes.concat(arrays[index++].getBytes(),
                                                    arrays[index++].getBytes(),
                                                    arrays[index++].getBytes(),
                                                    arrays[index++].getBytes());

                                            ipAddressMin = IpAddress.valueOf(IpAddress.Version.INET6, bytes);
                                        }
                                        if ((natAction.getRangePresent() & NAT_RANGE_IPV6_MAX) != 0) {
                                            byte[]  bytes = Bytes.concat(arrays[index++].getBytes(),
                                                    arrays[index++].getBytes(),
                                                    arrays[index++].getBytes(),
                                                    arrays[index++].getBytes());

                                            ipAddressMax = IpAddress.valueOf(IpAddress.Version.INET6, bytes);
                                        }
                                        if ((natAction.getRangePresent() & NAT_RANGE_PROTO_MIN) != 0) {
                                            portMin = arrays[index].getInt() >> 16 & 0x0000ffff;
                                        }
                                        if ((natAction.getRangePresent() & NAT_RANGE_PROTO_MAX) != 0) {
                                            portMax = arrays[index].getInt() & 0x0000ffff;
                                        }
                                        List<ExtensionTreatment> treatments = new ArrayList<>();
                                        NiciraNat natTreatment = new NiciraNat(natAction.getFlags(),
                                                natAction.getRangePresent(),
                                                portMin, portMax,
                                                ipAddressMin, ipAddressMax);
                                        treatments.add(natTreatment);
                                        return new NiciraCt(ctAction.getFlags(),
                                                ctAction.getZoneSrc(),
                                                ctAction.getZone(),
                                                ctAction.getRecircTable(),
                                                ctAction.getAlg(),
                                                treatments);
                                    default:
                                        throw new UnsupportedOperationException("Driver does not support nested" +
                                                " in ct action extension subtype " + actionNicira.getSubtype());
                                }
                            }
                        }
                        return new NiciraCt(ctAction.getFlags(),
                                ctAction.getZoneSrc(),
                                ctAction.getZone(),
                                ctAction.getRecircTable(),
                                ctAction.getAlg(),
                                new ArrayList<>());
                    case SUB_TYPE_CT_CLEAR:
                        return new NiciraCtClear();
                    default:
                        throw new UnsupportedOperationException("Driver does not support extension subtype "
                                + nicira.getSubtype());
                }
            }
        }
        return null;
    }

    @Override
    public ExtensionTreatment getExtensionInstruction(ExtensionTreatmentType type) {
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type())) {
            return new NiciraSetTunnelDst();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT.type())) {
            return new NiciraResubmit();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT_TABLE.type())) {
            return new NiciraResubmitTable();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI.type())) {
            return new NiciraSetNshSpi();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SI.type())) {
            return new NiciraSetNshSi();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH1.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH2.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH3.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4.type())) {
            return new NiciraSetNshContextHeader(type);
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_PUSH_NSH.type())) {
            return new NiciraPushNsh();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_POP_NSH.type())) {
            return new NiciraPopNsh();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_MDTYPE.type())) {
            return new NiciraNshMdType();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_NP.type())) {
            return new NiciraNshNp();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_SRC.type())) {
            return new NiciraEncapEthSrc();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_DST.type())) {
            return new NiciraEncapEthDst();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_TYPE.type())) {
            return new NiciraEncapEthType();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SHA_TO_THA.type())) {
            return NiciraMoveTreatmentFactory.createNiciraMovArpShaToTha();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SPA_TO_TPA.type())) {
            return NiciraMoveTreatmentFactory.createNiciraMovArpSpaToTpa();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ETH_SRC_TO_DST.type())) {
            return NiciraMoveTreatmentFactory.createNiciraMovEthSrcToDst();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())) {
            return NiciraMoveTreatmentFactory.createNiciraMovIpSrcToDst();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_TUN_GPE_NP.type())) {
            return new NiciraTunGpeNp();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C1_TO_C1.type())) {
            return NiciraMoveTreatmentFactory.createNiciraMovNshC1ToC1();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_C2.type())) {
            return NiciraMoveTreatmentFactory.createNiciraMovNshC2ToC2();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C3_TO_C3.type())) {
            return NiciraMoveTreatmentFactory.createNiciraMovNshC3ToC3();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C4_TO_C4.type())) {
            return NiciraMoveTreatmentFactory.createNiciraMovNshC4ToC4();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST
                .type())) {
            return NiciraMoveTreatmentFactory.createNiciraMovTunDstToTunDst();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_ID_TO_TUN_ID.type())) {
            return NiciraMoveTreatmentFactory.createNiciraMovTunIdToTunId();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_TUN_ID.type())) {
            return NiciraMoveTreatmentFactory.createNiciraMovNshC2ToTunId();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT.type())) {
            return new NiciraCt();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NAT.type())) {
            return new NiciraNat();
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT_CLEAR.type())) {
            return new NiciraCtClear();
        }
        throw new UnsupportedOperationException("Driver does not support extension type " + type.toString());
    }

    @Override
    public ObjectNode encode(ExtensionTreatment extensionTreatment, CodecContext context) {
        checkNotNull(extensionTreatment, "Extension treatment cannot be null");
        ExtensionTreatmentType type = extensionTreatment.type();
        ObjectNode root = context.mapper().createObjectNode();

        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type())) {
            NiciraSetTunnelDst tunnelDst = (NiciraSetTunnelDst) extensionTreatment;
            root.set(TUNNEL_DST, context.codec(NiciraSetTunnelDst.class).encode(tunnelDst, context));
        }

        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT.type())) {
            NiciraResubmit resubmit = (NiciraResubmit) extensionTreatment;
            root.set(RESUBMIT, context.codec(NiciraResubmit.class).encode(resubmit, context));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT_TABLE.type())) {
            NiciraResubmitTable resubmitTable = (NiciraResubmitTable) extensionTreatment;
            root.set(RESUBMIT_TABLE, context.codec(NiciraResubmitTable.class).encode(resubmitTable, context));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI.type())) {
            NiciraSetNshSpi niciraNshSpi = (NiciraSetNshSpi) extensionTreatment;
            root.set(NICIRA_NSH_SPI, context.codec(NiciraSetNshSpi.class).encode(niciraNshSpi, context));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SI.type())) {
            NiciraSetNshSi niciraNshSi = (NiciraSetNshSi) extensionTreatment;
            root.set(NICIRA_NSH_SI, context.codec(NiciraSetNshSi.class).encode(niciraNshSi, context));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH1.type())) {
            NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment;
            root.set(NICIRA_NSH_CH, context.codec(NiciraSetNshContextHeader.class).encode(niciraNshch, context));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH2.type())) {
            NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment;
            root.set(NICIRA_NSH_CH, context.codec(NiciraSetNshContextHeader.class).encode(niciraNshch, context));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH3.type())) {
            NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment;
            root.set(NICIRA_NSH_CH, context.codec(NiciraSetNshContextHeader.class).encode(niciraNshch, context));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4.type())) {
            NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment;
            root.set(NICIRA_NSH_CH, context.codec(NiciraSetNshContextHeader.class).encode(niciraNshch, context));
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SHA_TO_THA.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SPA_TO_TPA.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ETH_SRC_TO_DST.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())) {
            MoveExtensionTreatment mov = (MoveExtensionTreatment) extensionTreatment;
            root.set(NICIRA_MOVE, context.codec(MoveExtensionTreatment.class).encode(mov, context));
        }

        return root;
    }

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

        // parse extension type
        int typeInt = nullIsIllegal(json.get(TYPE), TYPE + MISSING_MEMBER_MESSAGE).asInt();
        ExtensionTreatmentType type = new ExtensionTreatmentType(typeInt);

        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type())) {
            return context.codec(NiciraSetTunnelDst.class).decode(json, context);
        }

        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT.type())) {
            return context.codec(NiciraResubmit.class).decode(json, context);
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT_TABLE.type())) {
            return context.codec(NiciraResubmitTable.class).decode(json, context);
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI.type())) {
            return context.codec(NiciraSetNshSpi.class).decode(json, context);
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SI.type())) {
            return context.codec(NiciraSetNshSi.class).decode(json, context);
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH1.type())) {
            return context.codec(NiciraSetNshContextHeader.class).decode(json, context);
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH2.type())) {
            return context.codec(NiciraSetNshContextHeader.class).decode(json, context);
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH3.type())) {
            return context.codec(NiciraSetNshContextHeader.class).decode(json, context);
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4.type())) {
            return context.codec(NiciraSetNshContextHeader.class).decode(json, context);
        }
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SHA_TO_THA.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SPA_TO_TPA.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ETH_SRC_TO_DST.type())
                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())) {
            return context.codec(MoveExtensionTreatment.class).decode(json, context);
        }
        throw new UnsupportedOperationException(
                "Driver does not support extension type " + type.toString());
    }
}
