/*
 * Copyright 2015-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.codec.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Maps;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.EthType;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
import org.onlab.util.HexString;
import org.onosproject.codec.CodecContext;
import org.onosproject.net.flow.ExtensionTreatmentCodec;
import org.onosproject.core.GroupId;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.GridType;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.StatTriggerField;
import org.onosproject.net.flow.StatTriggerFlag;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.L0ModificationInstruction;
import org.onosproject.net.flow.instructions.L1ModificationInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction;
import org.onosproject.net.flow.instructions.L4ModificationInstruction;
import org.onosproject.net.meter.MeterId;
import org.slf4j.Logger;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.onlab.util.Tools.nullIsIllegal;
import static org.onosproject.codec.impl.InstructionCodec.STAT_PACKET_COUNT;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Decoding portion of the instruction codec.
 */
public final class DecodeInstructionCodecHelper {
    protected static final Logger log = getLogger(DecodeInstructionCodecHelper.class);
    private final ObjectNode json;
    private final CodecContext context;
    private static final Pattern ETHTYPE_PATTERN = Pattern.compile("0x([0-9a-fA-F]{4})");

    /**
     * Creates a decode instruction codec object.
     *
     * @param json JSON object to decode
     * @param context codec context
     */
    public DecodeInstructionCodecHelper(ObjectNode json, CodecContext context) {
        this.json = json;
        this.context = context;
    }

    /**
     * Decodes a Layer 2 instruction.
     *
     * @return instruction object decoded from the JSON
     * @throws IllegalArgumentException if the JSON is invalid
     */
    private Instruction decodeL2() {
        String subType = nullIsIllegal(json.get(InstructionCodec.SUBTYPE),
                InstructionCodec.SUBTYPE + InstructionCodec.ERROR_MESSAGE).asText();

        if (subType.equals(L2ModificationInstruction.L2SubType.ETH_SRC.name())) {
            String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
                    InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
            return Instructions.modL2Src(MacAddress.valueOf(mac));
        } else if (subType.equals(L2ModificationInstruction.L2SubType.ETH_DST.name())) {
            String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
                    InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
            return Instructions.modL2Dst(MacAddress.valueOf(mac));
        } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_ID.name())) {
            short vlanId = (short) nullIsIllegal(json.get(InstructionCodec.VLAN_ID),
                    InstructionCodec.VLAN_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
            return Instructions.modVlanId(VlanId.vlanId(vlanId));
        } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PCP.name())) {
            byte vlanPcp = (byte) nullIsIllegal(json.get(InstructionCodec.VLAN_PCP),
                    InstructionCodec.VLAN_PCP + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
            return Instructions.modVlanPcp(vlanPcp);
        } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_LABEL.name())) {
            int label = nullIsIllegal(json.get(InstructionCodec.MPLS_LABEL),
                    InstructionCodec.MPLS_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
            return Instructions.modMplsLabel(MplsLabel.mplsLabel(label));
        } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_PUSH.name())) {
            return Instructions.pushMpls();
        } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_POP.name())) {
            if (json.has(InstructionCodec.ETHERNET_TYPE)) {
                return Instructions.popMpls(getEthType());
            }
            return Instructions.popMpls();
        } else if (subType.equals(L2ModificationInstruction.L2SubType.DEC_MPLS_TTL.name())) {
            return Instructions.decMplsTtl();
        } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_POP.name())) {
            return Instructions.popVlan();
        } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PUSH.name())) {
            if (json.has(InstructionCodec.ETHERNET_TYPE)) {
                return Instructions.pushVlan(getEthType());
            }
            return Instructions.pushVlan();
        } else if (subType.equals(L2ModificationInstruction.L2SubType.TUNNEL_ID.name())) {
            long tunnelId = nullIsIllegal(json.get(InstructionCodec.TUNNEL_ID),
                    InstructionCodec.TUNNEL_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong();
            return Instructions.modTunnelId(tunnelId);
        }
        throw new IllegalArgumentException("L2 Instruction subtype "
                + subType + " is not supported");
    }

    /**
     * Decodes a Layer 3 instruction.
     *
     * @return instruction object decoded from the JSON
     * @throws IllegalArgumentException if the JSON is invalid
     */
    private Instruction decodeL3() {
        String subType = nullIsIllegal(json.get(InstructionCodec.SUBTYPE),
                InstructionCodec.SUBTYPE + InstructionCodec.ERROR_MESSAGE).asText();

        if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_SRC.name())) {
            IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
                    InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
            return Instructions.modL3Src(ip);
        } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_DST.name())) {
            IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
                    InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
            return Instructions.modL3Dst(ip);
        } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_SRC.name())) {
            IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
                    InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
            return Instructions.modL3IPv6Src(ip);
        } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_DST.name())) {
            IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
                    InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
            return Instructions.modL3IPv6Dst(ip);
        } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_FLABEL.name())) {
            int flowLabel = nullIsIllegal(json.get(InstructionCodec.FLOW_LABEL),
                    InstructionCodec.FLOW_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
            return Instructions.modL3IPv6FlowLabel(flowLabel);
        } else  if (subType.equals(L3ModificationInstruction.L3SubType.TTL_IN.name())) {
            return Instructions.copyTtlIn();
        } else  if (subType.equals(L3ModificationInstruction.L3SubType.TTL_OUT.name())) {
            return Instructions.copyTtlOut();
        } else  if (subType.equals(L3ModificationInstruction.L3SubType.DEC_TTL.name())) {
            return Instructions.decNwTtl();
        }
        throw new IllegalArgumentException("L3 Instruction subtype "
                + subType + " is not supported");
    }

    /**
     * Decodes a Layer 0 instruction.
     *
     * @return instruction object decoded from the JSON
     * @throws IllegalArgumentException if the JSON is invalid
     */
    private Instruction decodeL0() {
        String subType = nullIsIllegal(json.get(InstructionCodec.SUBTYPE),
                InstructionCodec.SUBTYPE + InstructionCodec.ERROR_MESSAGE).asText();

        if (subType.equals(L0ModificationInstruction.L0SubType.OCH.name())) {
            String gridTypeString = nullIsIllegal(json.get(InstructionCodec.GRID_TYPE),
                    InstructionCodec.GRID_TYPE + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
            GridType gridType = GridType.valueOf(gridTypeString);
            if (gridType == null) {
                throw new IllegalArgumentException("Unknown grid type  "
                        + gridTypeString);
            }
            String channelSpacingString = nullIsIllegal(json.get(InstructionCodec.CHANNEL_SPACING),
                    InstructionCodec.CHANNEL_SPACING + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
            ChannelSpacing channelSpacing = ChannelSpacing.valueOf(channelSpacingString);
            if (channelSpacing == null) {
                throw new IllegalArgumentException("Unknown channel spacing  "
                        + channelSpacingString);
            }
            int spacingMultiplier = nullIsIllegal(json.get(InstructionCodec.SPACING_MULTIPLIER),
                    InstructionCodec.SPACING_MULTIPLIER + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
            int slotGranularity = nullIsIllegal(json.get(InstructionCodec.SLOT_GRANULARITY),
                    InstructionCodec.SLOT_GRANULARITY + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
            return Instructions.modL0Lambda(new OchSignal(gridType, channelSpacing,
                    spacingMultiplier, slotGranularity));
        }
        throw new IllegalArgumentException("L0 Instruction subtype "
                + subType + " is not supported");
    }

    /**
     * Decodes a Layer 1 instruction.
     *
     * @return instruction object decoded from the JSON
     * @throws IllegalArgumentException if the JSON is invalid
     */
    private Instruction decodeL1() {
        String subType = nullIsIllegal(json.get(InstructionCodec.SUBTYPE),
                InstructionCodec.SUBTYPE + InstructionCodec.ERROR_MESSAGE).asText();
        if (subType.equals(L1ModificationInstruction.L1SubType.ODU_SIGID.name())) {
            int tributaryPortNumber = nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_PORT_NUMBER),
                    InstructionCodec.TRIBUTARY_PORT_NUMBER + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
            int tributarySlotLen = nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_SLOT_LEN),
                    InstructionCodec.TRIBUTARY_SLOT_LEN + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
            byte[] tributarySlotBitmap = null;
            tributarySlotBitmap = HexString.fromHexString(
                    nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_SLOT_BITMAP),
                    InstructionCodec.TRIBUTARY_SLOT_BITMAP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
            return Instructions.modL1OduSignalId(OduSignalId.oduSignalId(tributaryPortNumber, tributarySlotLen,
                    tributarySlotBitmap));
        }
        throw new IllegalArgumentException("L1 Instruction subtype "
                + subType + " is not supported");
    }

    /**
     * Decodes a Layer 4 instruction.
     *
     * @return instruction object decoded from the JSON
     * @throws IllegalArgumentException if the JSON is invalid
     */
    private Instruction decodeL4() {
        String subType = nullIsIllegal(json.get(InstructionCodec.SUBTYPE),
                InstructionCodec.SUBTYPE + InstructionCodec.ERROR_MESSAGE).asText();

        if (subType.equals(L4ModificationInstruction.L4SubType.TCP_DST.name())) {
            TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
                    InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
            return Instructions.modTcpDst(tcpPort);
        } else if (subType.equals(L4ModificationInstruction.L4SubType.TCP_SRC.name())) {
            TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
                    InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
            return Instructions.modTcpSrc(tcpPort);
        } else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_DST.name())) {
            TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
                    InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
            return Instructions.modUdpDst(udpPort);
        } else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_SRC.name())) {
            TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
                    InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
            return Instructions.modUdpSrc(udpPort);
        }
        throw new IllegalArgumentException("L4 Instruction subtype "
                + subType + " is not supported");
    }

    private Instruction decodeStatTrigger() {
        String statTriggerFlag = nullIsIllegal(json.get(InstructionCodec.STAT_TRIGGER_FLAG),
                InstructionCodec.STAT_TRIGGER_FLAG + InstructionCodec.ERROR_MESSAGE).asText();

        StatTriggerFlag flag = null;

        if (statTriggerFlag.equals(StatTriggerFlag.ONLY_FIRST.name())) {
            flag = StatTriggerFlag.ONLY_FIRST;
        } else if (statTriggerFlag.equals(StatTriggerFlag.PERIODIC.name())) {
            flag = StatTriggerFlag.PERIODIC;
        } else {
            throw new IllegalArgumentException("statTriggerFlag "
                    + statTriggerFlag + " is not supported");
        }
        if (!json.has(InstructionCodec.STAT_THRESHOLDS)) {
            throw new IllegalArgumentException("statThreshold is not added");
        }
        JsonNode statThresholdsNode = nullIsIllegal(json.get(InstructionCodec.STAT_THRESHOLDS),
                InstructionCodec.STAT_THRESHOLDS + InstructionCodec.ERROR_MESSAGE);
        Map<StatTriggerField, Long> statThresholdMap = getStatThreshold(statThresholdsNode);
        if (statThresholdMap.isEmpty()) {
            throw new IllegalArgumentException("statThreshold must have at least one property");
        }
        return Instructions.statTrigger(statThresholdMap, flag);
    }

    private Map<StatTriggerField, Long> getStatThreshold(JsonNode statThresholdNode) {
        Map<StatTriggerField, Long> statThresholdMap = Maps.newEnumMap(StatTriggerField.class);
        for (JsonNode jsonNode : statThresholdNode) {
            if (jsonNode.hasNonNull(InstructionCodec.STAT_BYTE_COUNT)) {
                JsonNode byteCountNode = jsonNode.get(InstructionCodec.STAT_BYTE_COUNT);
                if (!byteCountNode.isNull() && byteCountNode.isNumber()) {
                    statThresholdMap.put(StatTriggerField.BYTE_COUNT, byteCountNode.asLong());
                }
            } else if (jsonNode.hasNonNull(STAT_PACKET_COUNT)) {
                JsonNode packetCount = jsonNode.get(STAT_PACKET_COUNT);
                if (!packetCount.isNull() && packetCount.isNumber()) {
                    statThresholdMap.put(StatTriggerField.PACKET_COUNT, packetCount.asLong());
                }
            } else if (jsonNode.hasNonNull(InstructionCodec.STAT_DURATION)) {
                JsonNode duration = jsonNode.get(InstructionCodec.STAT_DURATION);
                if (!duration.isNull() && duration.isNumber()) {
                    statThresholdMap.put(StatTriggerField.DURATION, duration.asLong());
                }
            } else {
                log.error("Unsupported stat {}", jsonNode.toString());
            }
        }

        return statThresholdMap;
    }

    /**
     * Decodes a extension instruction.
     *
     * @return extension treatment
     */
    private Instruction decodeExtension() {
        ObjectNode node = (ObjectNode) json.get(InstructionCodec.EXTENSION);
        if (node != null) {
            DeviceId deviceId = getDeviceId();

            ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
            DeviceService deviceService = serviceDirectory.get(DeviceService.class);
            Device device = deviceService.getDevice(deviceId);

            if (device == null) {
                throw new IllegalArgumentException("Device not found");
            }

            if (device.is(ExtensionTreatmentCodec.class)) {
                ExtensionTreatmentCodec treatmentCodec = device.as(ExtensionTreatmentCodec.class);
                ExtensionTreatment treatment = treatmentCodec.decode(node, context);
                return Instructions.extension(treatment, deviceId);
            } else {
                throw new IllegalArgumentException(
                        "There is no codec to decode extension for device " + deviceId.toString());
            }
        }
        return null;
    }

    /**
     * Returns device identifier.
     *
     * @return device identifier
     * @throws IllegalArgumentException if the JSON is invalid
     */
    private DeviceId getDeviceId() {
        JsonNode deviceIdNode = json.get(InstructionCodec.DEVICE_ID);
        if (deviceIdNode != null) {
            return DeviceId.deviceId(deviceIdNode.asText());
        }
        throw new IllegalArgumentException("Empty device identifier");
    }

    /**
     * Extracts port number of the given json node.
     *
     * @param jsonNode json node
     * @return port number
     */
    private PortNumber getPortNumber(ObjectNode jsonNode) {
        PortNumber portNumber;
        JsonNode portNode = nullIsIllegal(jsonNode.get(InstructionCodec.PORT),
                InstructionCodec.PORT + InstructionCodec.ERROR_MESSAGE);
        if (portNode.isLong() || portNode.isInt()) {
            portNumber = PortNumber.portNumber(portNode.asLong());
        } else if (portNode.isTextual()) {
            portNumber = PortNumber.fromString(portNode.textValue());
        } else {
            throw new IllegalArgumentException("Port value "
                    + portNode.toString()
                    + " is not supported");
        }
        return portNumber;
    }

    /**
     * Returns Ethernet type.
     *
     * @return ethernet type
     * @throws IllegalArgumentException if the JSON is invalid
     */
    private EthType getEthType() {
        String ethTypeStr = nullIsIllegal(json.get(InstructionCodec.ETHERNET_TYPE),
                  InstructionCodec.ETHERNET_TYPE + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
        Matcher matcher = ETHTYPE_PATTERN.matcher(ethTypeStr);
        if (!matcher.matches()) {
            throw new IllegalArgumentException("ETHERNET_TYPE must be a four digit hex string starting with 0x");
        }
        short ethernetType = (short) Integer.parseInt(matcher.group(1), 16);
        return new EthType(ethernetType);
    }

    /**
     * Decodes the JSON into an instruction object.
     *
     * @return Criterion object
     * @throws IllegalArgumentException if the JSON is invalid
     */
    public Instruction decode() {
        String type = nullIsIllegal(json.get(InstructionCodec.TYPE),
                InstructionCodec.TYPE + InstructionCodec.ERROR_MESSAGE).asText();

        if (type.equals(Instruction.Type.OUTPUT.name())) {
            return Instructions.createOutput(getPortNumber(json));
        } else if (type.equals(Instruction.Type.NOACTION.name())) {
            return Instructions.createNoAction();
        } else if (type.equals(Instruction.Type.TABLE.name())) {
            return Instructions.transition(nullIsIllegal(json.get(InstructionCodec.TABLE_ID),
                    InstructionCodec.TABLE_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
        } else if (type.equals(Instruction.Type.GROUP.name())) {
            GroupId groupId = new GroupId(nullIsIllegal(json.get(InstructionCodec.GROUP_ID),
                    InstructionCodec.GROUP_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
            return Instructions.createGroup(groupId);
        } else if (type.equals(Instruction.Type.METER.name())) {
            MeterId meterId = MeterId.meterId(nullIsIllegal(json.get(InstructionCodec.METER_ID),
                    InstructionCodec.METER_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong());
            return Instructions.meterTraffic(meterId);
        } else if (type.equals(Instruction.Type.QUEUE.name())) {
            long queueId = nullIsIllegal(json.get(InstructionCodec.QUEUE_ID),
                    InstructionCodec.QUEUE_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong();
            if (json.get(InstructionCodec.PORT) == null ||
                    json.get(InstructionCodec.PORT).isNull()) {
                return Instructions.setQueue(queueId, null);
            } else {
                return Instructions.setQueue(queueId, getPortNumber(json));
            }
        } else if (type.equals(Instruction.Type.L0MODIFICATION.name())) {
            return decodeL0();
        } else if (type.equals(Instruction.Type.L1MODIFICATION.name())) {
            return decodeL1();
        } else if (type.equals(Instruction.Type.L2MODIFICATION.name())) {
            return decodeL2();
        } else if (type.equals(Instruction.Type.L3MODIFICATION.name())) {
            return decodeL3();
        } else if (type.equals(Instruction.Type.L4MODIFICATION.name())) {
            return decodeL4();
        } else if (type.equals(Instruction.Type.EXTENSION.name())) {
            return decodeExtension();
        } else if (type.equals(Instruction.Type.STAT_TRIGGER.name())) {
            return decodeStatTrigger();
        }
        throw new IllegalArgumentException("Instruction type "
                + type + " is not supported");
    }
}
