/*
 * 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 com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.packet.VlanId;
import org.onosproject.codec.CodecContext;
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.OFActionOfdpa;
import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaMplsL2Port;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaMplsType;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaOvid;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaQosIndex;
import org.projectfloodlight.openflow.types.U16;
import org.projectfloodlight.openflow.types.U32;
import org.projectfloodlight.openflow.types.U8;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;

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

    private static final int TYPE_OFDPA = 0x1018;
    private static final int SUB_TYPE_PUSH_L2_HEADER = 1;
    private static final int SUB_TYPE_POP_L2_HEADER = 2;
    private static final int SUB_TYPE_PUSH_CW = 3;
    private static final int SUB_TYPE_POP_CW = 4;

    private static final String TYPE = "type";
    private static final String MISSING_MEMBER_MESSAGE = " member is required in Ofdpa3ExtensionTreatmentInterpreter";
    private static final String MISSING_TREATMENT_MESSAGE = "Extension treatment cannot be null";
    private static final String NOT_SUPPORTED_MESSAGE = "Driver does not support extension type of ";

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

    @Override
    public boolean supported(ExtensionTreatmentType extensionTreatmentType) {
        if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type())) {
            return true;
        } else if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type())) {
            return true;
        } else if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.type())) {
            return true;
        } else if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_QOS_INDEX.type())) {
            return true;
        } else if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_L2_HEADER.type())) {
            return true;
        } else if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_CW.type())) {
            return true;
        } else if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_L2_HEADER.type())) {
            return true;
        } else if (extensionTreatmentType.equals(
                ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_CW.type())) {
            return true;
        }
        return false;
    }

    @Override
    public OFAction mapInstruction(OFFactory factory, ExtensionTreatment extensionTreatment) {
        ExtensionTreatmentType type = extensionTreatment.type();
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type())) {
            short mplsType = ((Ofdpa3SetMplsType) extensionTreatment).mplsType();
            return factory.actions().setField(factory.oxms().ofdpaMplsType(
                    U16.ofRaw(mplsType)));
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type())) {
            // OFDPA requires isPresent bit set to 1 for OVID.
            VlanId vlanId = ((Ofdpa3SetOvid) extensionTreatment).vlanId();
            short mask = (short) 0x1000;
            short oVid = (short) (mask | vlanId.toShort());
            return factory.actions().setField(factory.oxms().ofdpaOvid(
                    U16.ofRaw(oVid)));
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.type())) {
            Integer mplsL2Port = ((Ofdpa3SetMplsL2Port) extensionTreatment).mplsL2Port();
            /*
             * 0x0000XXXX UNI Interface.
             * 0x0002XXXX NNI Interface
             */
            if ((mplsL2Port >= 0 && mplsL2Port <= 0x0000FFFF) ||
                    (mplsL2Port >= 0x00020000 && mplsL2Port <= 0x0002FFFF)) {
                return factory.actions().setField(
                        factory.oxms().ofdpaMplsL2Port(U32.ofRaw(mplsL2Port))
                );
            }
            throw new UnsupportedOperationException(
                    "Unexpected ExtensionTreatment: " + extensionTreatment.toString());
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_QOS_INDEX.type())) {
            Integer qosIndex = ((Ofdpa3SetQosIndex) extensionTreatment).qosIndex();
            /*
             * Qos index is a single byte [0...255]
             */
            if (qosIndex >= 0 && qosIndex <= 255) {
                return factory.actions().setField(
                        factory.oxms().ofdpaQosIndex(U8.ofRaw((byte) (qosIndex & 0xFF)))
                );
            }
            throw new UnsupportedOperationException(
                    "Unexpected ExtensionTreatment: " + extensionTreatment.toString());
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_L2_HEADER.type())) {
            return factory.actions().ofdpaPushL2Header();
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_CW.type())) {
            return factory.actions().ofdpaPushCw();
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_L2_HEADER.type())) {
            return factory.actions().ofdpaPopL2Header();
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_CW.type())) {
            return factory.actions().ofdpaPopCw();
        }
        throw new UnsupportedOperationException(
                "Unexpected ExtensionTreatment: " + extensionTreatment.toString());
    }

    @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 OFDPA_MPLS_TYPE:
                    OFOxmOfdpaMplsType mplsType = (OFOxmOfdpaMplsType) oxm;
                    return new Ofdpa3SetMplsType(mplsType.getValue().getRaw());
                case OFDPA_OVID:
                    OFOxmOfdpaOvid ovid = ((OFOxmOfdpaOvid) oxm);
                    short mask = (short) 0x0FFF;
                    short oVid = (short) (mask & ovid.getValue().getRaw());
                    VlanId vlanId = VlanId.vlanId(oVid);
                    return new Ofdpa3SetOvid(vlanId);
                case OFDPA_MPLS_L2_PORT:
                    OFOxmOfdpaMplsL2Port mplsl2Port = ((OFOxmOfdpaMplsL2Port) oxm);
                    Integer mplsL2Port = mplsl2Port.getValue().getRaw();
                    if ((mplsL2Port >= 0 && mplsL2Port <= 0x0000FFFF) ||
                            (mplsL2Port >= 0x00020000 && mplsL2Port <= 0x0002FFFF)) {
                        return new Ofdpa3SetMplsL2Port(mplsL2Port);
                    }
                    break;
                case OFDPA_QOS_INDEX:
                    OFOxmOfdpaQosIndex qosindex = ((OFOxmOfdpaQosIndex) oxm);
                    Integer qosIndex = (int) qosindex.getValue().getRaw();
                    if (qosIndex >= 0 && qosIndex <= 255) {
                        return new Ofdpa3SetQosIndex(qosIndex);
                    }
                    break;
                default:
                    throw new UnsupportedOperationException(
                            "Driver does not support extension type " + oxm.getMatchField().id);
            }
        } else if (action.getType().equals(OFActionType.EXPERIMENTER)) {
            OFActionExperimenter experimenter = (OFActionExperimenter) action;
            if (Long.valueOf(experimenter.getExperimenter()).intValue() == TYPE_OFDPA) {
                OFActionOfdpa ofdpa = (OFActionOfdpa) experimenter;
                switch (ofdpa.getExpType()) {
                    case SUB_TYPE_PUSH_L2_HEADER:
                        return new Ofdpa3PushL2Header();
                    case SUB_TYPE_POP_L2_HEADER:
                        return new Ofdpa3PopL2Header();
                    case SUB_TYPE_PUSH_CW:
                        return new Ofdpa3PushCw();
                    case SUB_TYPE_POP_CW:
                        return new Ofdpa3PopCw();
                    default:
                        throw new UnsupportedOperationException(
                                "Unexpected OFAction: " + action.toString());
                }
            }
            throw new UnsupportedOperationException(
                    "Unexpected OFAction: " + action.toString());
        }
        throw new UnsupportedOperationException(
                "Unexpected OFAction: " + action.toString());
    }

    @Override
    public ExtensionTreatment getExtensionInstruction(ExtensionTreatmentType type) {
        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type())) {
            return new Ofdpa3SetMplsType();
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type())) {
            return new Ofdpa3SetOvid();
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.type())) {
            return new Ofdpa3SetMplsL2Port();
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_QOS_INDEX.type())) {
            return new Ofdpa3SetQosIndex();
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_L2_HEADER.type())) {
            return new Ofdpa3PushL2Header();
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_CW.type())) {
            return new Ofdpa3PushCw();
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_L2_HEADER.type())) {
            return new Ofdpa3PopL2Header();
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_CW.type())) {
            return new Ofdpa3PopCw();
        }
        throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE + type.toString());
    }

    @Override
    public ObjectNode encode(ExtensionTreatment extensionTreatment, CodecContext context) {
        checkNotNull(extensionTreatment, MISSING_TREATMENT_MESSAGE);
        ExtensionTreatmentType type = extensionTreatment.type();
        ObjectNode root = context.mapper().createObjectNode();

        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type())) {
            Ofdpa3SetMplsType setMplsType = (Ofdpa3SetMplsType) extensionTreatment;
            root.put(TYPE, ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.name());
            root.setAll(context.codec(Ofdpa3SetMplsType.class).encode(setMplsType, context));
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type())) {
            Ofdpa3SetOvid setOvid = (Ofdpa3SetOvid) extensionTreatment;
            root.put(TYPE, ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.name());
            root.setAll(context.codec(Ofdpa3SetOvid.class).encode(setOvid, context));
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.type())) {
            Ofdpa3SetMplsL2Port setMplsL2Port = (Ofdpa3SetMplsL2Port) extensionTreatment;
            root.put(TYPE, ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.name());
            root.setAll(context.codec(Ofdpa3SetMplsL2Port.class).encode(setMplsL2Port, context));
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_QOS_INDEX.type())) {
            Ofdpa3SetQosIndex setQosIndex = (Ofdpa3SetQosIndex) extensionTreatment;
            root.put(TYPE, ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_QOS_INDEX.name());
            root.setAll(context.codec(Ofdpa3SetQosIndex.class).encode(setQosIndex, context));
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_L2_HEADER.type())) {
            root.put(TYPE, ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_L2_HEADER.name());
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_CW.type())) {
            root.put(TYPE, ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_CW.name());
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_L2_HEADER.type())) {
            root.put(TYPE, ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_L2_HEADER.name());
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_CW.type())) {
            root.put(TYPE, ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_CW.name());
        }

        return root;
    }

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

        String type = nullIsIllegal(json.get(TYPE), TYPE + MISSING_MEMBER_MESSAGE).asText();

        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.name())) {
            return context.codec(Ofdpa3SetMplsType.class).decode(json, context);
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.name())) {
            return context.codec(Ofdpa3SetOvid.class).decode(json, context);
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.name())) {
            return context.codec(Ofdpa3SetMplsL2Port.class).decode(json, context);
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_QOS_INDEX.name())) {
            return context.codec(Ofdpa3SetQosIndex.class).decode(json, context);
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_L2_HEADER.name())) {
            return new Ofdpa3PushL2Header();
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_CW.name())) {
            return new Ofdpa3PushCw();
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_L2_HEADER.name())) {
            return new Ofdpa3PopL2Header();
        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_CW.name())) {
            return new Ofdpa3PopCw();
        } else {
            throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE + type.toString());
        }
    }
}
