/*
 * Copyright 2015 Open Networking Laboratory
 *
 * 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.node.ObjectNode;
import org.onlab.util.HexString;
import org.onosproject.codec.CodecContext;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalId;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthCriterion;
import org.onosproject.net.flow.criteria.EthTypeCriterion;
import org.onosproject.net.flow.criteria.IPCriterion;
import org.onosproject.net.flow.criteria.IPDscpCriterion;
import org.onosproject.net.flow.criteria.IPEcnCriterion;
import org.onosproject.net.flow.criteria.IPProtocolCriterion;
import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
import org.onosproject.net.flow.criteria.MetadataCriterion;
import org.onosproject.net.flow.criteria.MplsCriterion;
import org.onosproject.net.flow.criteria.OchSignalCriterion;
import org.onosproject.net.flow.criteria.OchSignalTypeCriterion;
import org.onosproject.net.flow.criteria.OduSignalIdCriterion;
import org.onosproject.net.flow.criteria.OduSignalTypeCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.criteria.SctpPortCriterion;
import org.onosproject.net.flow.criteria.TcpPortCriterion;
import org.onosproject.net.flow.criteria.TunnelIdCriterion;
import org.onosproject.net.flow.criteria.UdpPortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.criteria.VlanPcpCriterion;

import java.util.EnumMap;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Encode portion of the criterion codec.
 */
public final class EncodeCriterionCodecHelper {

    private final Criterion criterion;
    private final CodecContext context;

    private final EnumMap<Criterion.Type, CriterionTypeFormatter> formatMap;

    /**
     * Creates an encoder object for a criterion.
     * Initializes the formatter lookup map for the criterion subclasses.
     *
     * @param criterion Criterion to encode
     * @param context   context of the JSON encoding
     */
    public EncodeCriterionCodecHelper(Criterion criterion, CodecContext context) {
        this.criterion = criterion;
        this.context = context;

        formatMap = new EnumMap<>(Criterion.Type.class);

        formatMap.put(Criterion.Type.IN_PORT, new FormatInPort());
        formatMap.put(Criterion.Type.IN_PHY_PORT, new FormatInPort());
        formatMap.put(Criterion.Type.METADATA, new FormatMetadata());
        formatMap.put(Criterion.Type.ETH_DST, new FormatEth());
        formatMap.put(Criterion.Type.ETH_SRC, new FormatEth());
        formatMap.put(Criterion.Type.ETH_TYPE, new FormatEthType());
        formatMap.put(Criterion.Type.VLAN_VID, new FormatVlanVid());
        formatMap.put(Criterion.Type.VLAN_PCP, new FormatVlanPcp());
        formatMap.put(Criterion.Type.IP_DSCP, new FormatIpDscp());
        formatMap.put(Criterion.Type.IP_ECN, new FormatIpEcn());
        formatMap.put(Criterion.Type.IP_PROTO, new FormatIpProto());
        formatMap.put(Criterion.Type.IPV4_SRC, new FormatIp());
        formatMap.put(Criterion.Type.IPV4_DST, new FormatIp());
        formatMap.put(Criterion.Type.TCP_SRC, new FormatTcp());
        formatMap.put(Criterion.Type.TCP_DST, new FormatTcp());
        formatMap.put(Criterion.Type.UDP_SRC, new FormatUdp());
        formatMap.put(Criterion.Type.UDP_DST, new FormatUdp());
        formatMap.put(Criterion.Type.SCTP_SRC, new FormatSctp());
        formatMap.put(Criterion.Type.SCTP_DST, new FormatSctp());
        formatMap.put(Criterion.Type.ICMPV4_TYPE, new FormatIcmpV4Type());
        formatMap.put(Criterion.Type.ICMPV4_CODE, new FormatIcmpV4Code());
        formatMap.put(Criterion.Type.IPV6_SRC, new FormatIp());
        formatMap.put(Criterion.Type.IPV6_DST, new FormatIp());
        formatMap.put(Criterion.Type.IPV6_FLABEL, new FormatIpV6FLabel());
        formatMap.put(Criterion.Type.ICMPV6_TYPE, new FormatIcmpV6Type());
        formatMap.put(Criterion.Type.ICMPV6_CODE, new FormatIcmpV6Code());
        formatMap.put(Criterion.Type.IPV6_ND_TARGET, new FormatV6NDTarget());
        formatMap.put(Criterion.Type.IPV6_ND_SLL, new FormatV6NDTll());
        formatMap.put(Criterion.Type.IPV6_ND_TLL, new FormatV6NDTll());
        formatMap.put(Criterion.Type.MPLS_LABEL, new FormatMplsLabel());
        formatMap.put(Criterion.Type.IPV6_EXTHDR, new FormatIpV6Exthdr());
        formatMap.put(Criterion.Type.OCH_SIGID, new FormatOchSigId());
        formatMap.put(Criterion.Type.OCH_SIGTYPE, new FormatOchSigType());
        formatMap.put(Criterion.Type.TUNNEL_ID, new FormatTunnelId());
        formatMap.put(Criterion.Type.DUMMY, new FormatDummyType());
        formatMap.put(Criterion.Type.ODU_SIGID, new FormatOduSignalId());
        formatMap.put(Criterion.Type.ODU_SIGTYPE, new FormatOduSignalType());
        // Currently unimplemented
        formatMap.put(Criterion.Type.ARP_OP, new FormatUnknown());
        formatMap.put(Criterion.Type.ARP_SPA, new FormatUnknown());
        formatMap.put(Criterion.Type.ARP_TPA, new FormatUnknown());
        formatMap.put(Criterion.Type.ARP_SHA, new FormatUnknown());
        formatMap.put(Criterion.Type.ARP_THA, new FormatUnknown());
        formatMap.put(Criterion.Type.MPLS_TC, new FormatUnknown());
        formatMap.put(Criterion.Type.MPLS_BOS, new FormatUnknown());
        formatMap.put(Criterion.Type.PBB_ISID, new FormatUnknown());
        formatMap.put(Criterion.Type.UNASSIGNED_40, new FormatUnknown());
        formatMap.put(Criterion.Type.PBB_UCA, new FormatUnknown());
        formatMap.put(Criterion.Type.TCP_FLAGS, new FormatUnknown());
        formatMap.put(Criterion.Type.ACTSET_OUTPUT, new FormatUnknown());
        formatMap.put(Criterion.Type.PACKET_TYPE, new FormatUnknown());
        formatMap.put(Criterion.Type.EXTENSION, new FormatUnknown());
    }

    private interface CriterionTypeFormatter {
        ObjectNode encodeCriterion(ObjectNode root, Criterion criterion);
    }

    private static class FormatUnknown implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            return root;
        }
    }

    private static class FormatInPort implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final PortCriterion portCriterion = (PortCriterion) criterion;
            return root.put(CriterionCodec.PORT, portCriterion.port().toLong());
        }
    }

    private static class FormatMetadata implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final MetadataCriterion metadataCriterion =
                    (MetadataCriterion) criterion;
            return root.put(CriterionCodec.METADATA, metadataCriterion.metadata());
        }
    }

    private static class FormatEth implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final EthCriterion ethCriterion = (EthCriterion) criterion;
            return root.put(CriterionCodec.MAC, ethCriterion.mac().toString());
        }
    }

    private static class FormatEthType implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final EthTypeCriterion ethTypeCriterion =
                    (EthTypeCriterion) criterion;
            return root.put(CriterionCodec.ETH_TYPE, "0x"
                    + Integer.toHexString(ethTypeCriterion.ethType().toShort() & 0xffff));
        }
    }

    private static class FormatVlanVid implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final VlanIdCriterion vlanIdCriterion =
                    (VlanIdCriterion) criterion;
            return root.put(CriterionCodec.VLAN_ID, vlanIdCriterion.vlanId().toShort());
        }
    }

    private static class FormatVlanPcp implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final VlanPcpCriterion vlanPcpCriterion =
                    (VlanPcpCriterion) criterion;
            return root.put(CriterionCodec.PRIORITY, vlanPcpCriterion.priority());
        }
    }

    private static class FormatIpDscp implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final IPDscpCriterion ipDscpCriterion =
                    (IPDscpCriterion) criterion;
            return root.put(CriterionCodec.IP_DSCP, ipDscpCriterion.ipDscp());
        }
    }

    private static class FormatIpEcn implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final IPEcnCriterion ipEcnCriterion =
                    (IPEcnCriterion) criterion;
            return root.put(CriterionCodec.IP_ECN, ipEcnCriterion.ipEcn());
        }
    }

    private static class FormatIpProto implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final IPProtocolCriterion iPProtocolCriterion =
                    (IPProtocolCriterion) criterion;
            return root.put(CriterionCodec.PROTOCOL, iPProtocolCriterion.protocol());
        }
    }

    private static class FormatIp implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final IPCriterion iPCriterion = (IPCriterion) criterion;
            return root.put(CriterionCodec.IP, iPCriterion.ip().toString());
        }
    }

    private static class FormatTcp implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final TcpPortCriterion tcpPortCriterion =
                    (TcpPortCriterion) criterion;
            return root.put(CriterionCodec.TCP_PORT, tcpPortCriterion.tcpPort().toInt());
        }
    }

    private static class FormatUdp implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final UdpPortCriterion udpPortCriterion =
                    (UdpPortCriterion) criterion;
            return root.put(CriterionCodec.UDP_PORT, udpPortCriterion.udpPort().toInt());
        }
    }

    private static class FormatSctp implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final SctpPortCriterion sctpPortCriterion =
                    (SctpPortCriterion) criterion;
            return root.put(CriterionCodec.SCTP_PORT, sctpPortCriterion.sctpPort().toInt());
        }
    }

    private static class FormatIcmpV4Type implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final IcmpTypeCriterion icmpTypeCriterion =
                    (IcmpTypeCriterion) criterion;
            return root.put(CriterionCodec.ICMP_TYPE, icmpTypeCriterion.icmpType());
        }
    }

    private static class FormatIcmpV4Code implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final IcmpCodeCriterion icmpCodeCriterion =
                    (IcmpCodeCriterion) criterion;
            return root.put(CriterionCodec.ICMP_CODE, icmpCodeCriterion.icmpCode());
        }
    }

    private static class FormatIpV6FLabel implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final IPv6FlowLabelCriterion ipv6FlowLabelCriterion =
                    (IPv6FlowLabelCriterion) criterion;
            return root.put(CriterionCodec.FLOW_LABEL, ipv6FlowLabelCriterion.flowLabel());
        }
    }

    private static class FormatIcmpV6Type implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final Icmpv6TypeCriterion icmpv6TypeCriterion =
                    (Icmpv6TypeCriterion) criterion;
            return root.put(CriterionCodec.ICMPV6_TYPE, icmpv6TypeCriterion.icmpv6Type());
        }
    }

    private static class FormatIcmpV6Code implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final Icmpv6CodeCriterion icmpv6CodeCriterion =
                    (Icmpv6CodeCriterion) criterion;
            return root.put(CriterionCodec.ICMPV6_CODE, icmpv6CodeCriterion.icmpv6Code());
        }
    }

    private static class FormatV6NDTarget implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final IPv6NDTargetAddressCriterion ipv6NDTargetAddressCriterion
                    = (IPv6NDTargetAddressCriterion) criterion;
            return root.put(CriterionCodec.TARGET_ADDRESS, ipv6NDTargetAddressCriterion.targetAddress().toString());
        }
    }

    private static class FormatV6NDTll implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final IPv6NDLinkLayerAddressCriterion ipv6NDLinkLayerAddressCriterion
                    = (IPv6NDLinkLayerAddressCriterion) criterion;
            return root.put(CriterionCodec.MAC, ipv6NDLinkLayerAddressCriterion.mac().toString());
        }
    }

    private static class FormatMplsLabel implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final MplsCriterion mplsCriterion =
                    (MplsCriterion) criterion;
            return root.put(CriterionCodec.LABEL, mplsCriterion.label().toInt());
        }
    }

    private static class FormatIpV6Exthdr implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final IPv6ExthdrFlagsCriterion exthdrCriterion =
                    (IPv6ExthdrFlagsCriterion) criterion;
            return root.put(CriterionCodec.EXT_HDR_FLAGS, exthdrCriterion.exthdrFlags());
        }
    }

    private static class FormatOchSigId implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            OchSignal ochSignal = ((OchSignalCriterion) criterion).lambda();
            ObjectNode child = root.putObject(CriterionCodec.OCH_SIGNAL_ID);

            child.put(CriterionCodec.GRID_TYPE, ochSignal.gridType().name());
            child.put(CriterionCodec.CHANNEL_SPACING, ochSignal.channelSpacing().name());
            child.put(CriterionCodec.SPACING_MULIPLIER, ochSignal.spacingMultiplier());
            child.put(CriterionCodec.SLOT_GRANULARITY, ochSignal.slotGranularity());

            return root;
        }
    }

    private static class FormatOchSigType implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final OchSignalTypeCriterion ochSignalTypeCriterion =
                    (OchSignalTypeCriterion) criterion;
            return root.put(CriterionCodec.OCH_SIGNAL_TYPE, ochSignalTypeCriterion.signalType().name());
        }
    }

    private static class FormatTunnelId implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final TunnelIdCriterion tunnelIdCriterion =
                    (TunnelIdCriterion) criterion;
            return root.put(CriterionCodec.TUNNEL_ID, tunnelIdCriterion.tunnelId());
        }
    }

    private static class FormatOduSignalId implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            OduSignalId oduSignalId = ((OduSignalIdCriterion) criterion).oduSignalId();
            ObjectNode child = root.putObject(CriterionCodec.ODU_SIGNAL_ID);

            child.put(CriterionCodec.TRIBUTARY_PORT_NUMBER, oduSignalId.tributaryPortNumber());
            child.put(CriterionCodec.TRIBUTARY_SLOT_LEN, oduSignalId.tributarySlotLength());
            child.put(CriterionCodec.TRIBUTARY_SLOT_BITMAP, HexString.toHexString(oduSignalId.tributarySlotBitmap()));

            return root;
        }
    }


    private static class FormatOduSignalType implements CriterionTypeFormatter {
        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            final OduSignalTypeCriterion oduSignalTypeCriterion =
                    (OduSignalTypeCriterion) criterion;
            return root.put(CriterionCodec.ODU_SIGNAL_TYPE, oduSignalTypeCriterion.signalType().name());
        }
    }

    private class FormatDummyType implements CriterionTypeFormatter {

        @Override
        public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
            checkNotNull(criterion, "Criterion cannot be null");

            return root.put(CriterionCodec.TYPE, criterion.type().toString());

        }
    }

    /**
     * Encodes a criterion into a JSON node.
     *
     * @return encoded JSON object for the given criterion
     */
    public ObjectNode encode() {
        final ObjectNode result = context.mapper().createObjectNode()
                .put(CriterionCodec.TYPE, criterion.type().toString());

        CriterionTypeFormatter formatter =
                checkNotNull(
                        formatMap.get(criterion.type()),
                        "No formatter found for criterion type "
                                + criterion.type().toString());

        return formatter.encodeCriterion(result, criterion);
    }

}
