/*
 * Copyright 2014-present 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.net.flow.instructions;

import com.google.common.base.MoreObjects;
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.onosproject.core.GroupId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Lambda;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction;
import org.onosproject.net.flow.instructions.L1ModificationInstruction.ModOduSignalIdInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction;
import org.onosproject.net.flow.instructions.L4ModificationInstruction.L4SubType;
import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
import org.onosproject.net.meter.MeterId;

import java.util.Objects;

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

/**
 * Factory class for creating various traffic treatment instructions.
 */
public final class Instructions {

    private static final String SEPARATOR = ":";

    // Ban construction
    private Instructions() {}

    /**
     * Creates an output instruction using the specified port number. This can
     * include logical ports such as CONTROLLER, FLOOD, etc.
     *
     * @param number port number
     * @return output instruction
     */
    public static OutputInstruction createOutput(final PortNumber number) {
        checkNotNull(number, "PortNumber cannot be null");
        return new OutputInstruction(number);
    }

    /**
     * Creates a no action instruction.
     *
     * @return no action instruction
     */
    public static NoActionInstruction createNoAction() {
        return new NoActionInstruction();
    }

    /**
     * Creates a group instruction.
     *
     * @param groupId Group Id
     * @return group instruction
     */
    public static GroupInstruction createGroup(final GroupId groupId) {
        checkNotNull(groupId, "GroupId cannot be null");
        return new GroupInstruction(groupId);
    }

    /**
     * Creates a set-queue instruction.
     *
     * @param queueId Queue Id
     * @param port Port number
     * @return set-queue instruction
     */
    public static SetQueueInstruction setQueue(final long queueId, final PortNumber port) {
        checkNotNull(queueId, "queue ID cannot be null");
        return new SetQueueInstruction(queueId, port);
    }

    /**
     * Creates a meter instruction.
     *
     * @param meterId Meter Id
     * @return meter instruction
     */
    public static MeterInstruction meterTraffic(final MeterId meterId) {
        checkNotNull(meterId, "meter id cannot be null");
        return new MeterInstruction(meterId);
    }

    /**
     * Creates an L0 modification with the specified OCh signal.
     *
     * @param lambda OCh signal
     * @return an L0 modification
     */
    public static L0ModificationInstruction modL0Lambda(Lambda lambda) {
        checkNotNull(lambda, "L0 OCh signal cannot be null");

        if (lambda instanceof OchSignal) {
            return new ModOchSignalInstruction((OchSignal) lambda);
        } else {
            throw new UnsupportedOperationException(String.format("Unsupported type: %s", lambda));
        }
    }

    /**
     * Creates an L1 modification with the specified ODU signal Id.
     *
     * @param oduSignalId ODU Signal Id
     * @return a L1 modification
     */
    public static L1ModificationInstruction modL1OduSignalId(OduSignalId oduSignalId) {
        checkNotNull(oduSignalId, "L1 ODU signal ID cannot be null");
        return new ModOduSignalIdInstruction(oduSignalId);
    }
    /**
     * Creates a l2 src modification.
     *
     * @param addr the mac address to modify to
     * @return a l2 modification
     */
    public static L2ModificationInstruction modL2Src(MacAddress addr) {
        checkNotNull(addr, "Src l2 address cannot be null");
        return new L2ModificationInstruction.ModEtherInstruction(
                L2ModificationInstruction.L2SubType.ETH_SRC, addr);
    }

    /**
     * Creates a L2 dst modification.
     *
     * @param addr the mac address to modify to
     * @return a L2 modification
     */
    public static L2ModificationInstruction modL2Dst(MacAddress addr) {
        checkNotNull(addr, "Dst l2 address cannot be null");
        return new L2ModificationInstruction.ModEtherInstruction(
                L2ModificationInstruction.L2SubType.ETH_DST, addr);
    }

    /**
     * Creates a VLAN ID modification.
     *
     * @param vlanId the VLAN ID to modify to
     * @return a L2 modification
     */
    public static L2ModificationInstruction modVlanId(VlanId vlanId) {
        checkNotNull(vlanId, "VLAN id cannot be null");
        return new L2ModificationInstruction.ModVlanIdInstruction(vlanId);
    }

    /**
     * Creates a VLAN PCP modification.
     *
     * @param vlanPcp the PCP to modify to
     * @return a L2 modification
     */
    public static L2ModificationInstruction modVlanPcp(Byte vlanPcp) {
        checkNotNull(vlanPcp, "VLAN Pcp cannot be null");
        return new L2ModificationInstruction.ModVlanPcpInstruction(vlanPcp);
    }

    /**
     * Creates a MPLS label modification.
     *
     * @param mplsLabel MPLS label to set
     * @return a L2 Modification
     */
    public static L2ModificationInstruction modMplsLabel(MplsLabel mplsLabel) {
        checkNotNull(mplsLabel, "MPLS label cannot be null");
        return new L2ModificationInstruction.ModMplsLabelInstruction(mplsLabel);
    }

    /**
     * Creates a MPLS BOS bit modification.
     *
     * @param mplsBos MPLS BOS bit to set (true) or unset (false)
     * @return a L2 Modification
     */
    public static L2ModificationInstruction modMplsBos(boolean mplsBos) {
        return new L2ModificationInstruction.ModMplsBosInstruction(mplsBos);
    }

    /**
     * Creates a MPLS decrement TTL modification.
     *
     * @return a L2 Modification
     */
    public static L2ModificationInstruction decMplsTtl() {
        return new L2ModificationInstruction.ModMplsTtlInstruction();
    }

    /**
     * Creates a L3 IPv4 src modification.
     *
     * @param addr the IPv4 address to modify to
     * @return a L3 modification
     */
    public static L3ModificationInstruction modL3Src(IpAddress addr) {
        checkNotNull(addr, "Src l3 IPv4 address cannot be null");
        return new ModIPInstruction(L3SubType.IPV4_SRC, addr);
    }

    /**
     * Creates a L3 IPv4 dst modification.
     *
     * @param addr the IPv4 address to modify to
     * @return a L3 modification
     */
    public static L3ModificationInstruction modL3Dst(IpAddress addr) {
        checkNotNull(addr, "Dst l3 IPv4 address cannot be null");
        return new ModIPInstruction(L3SubType.IPV4_DST, addr);
    }

    /**
     * Creates a L3 IPv6 src modification.
     *
     * @param addr the IPv6 address to modify to
     * @return a L3 modification
     */
    public static L3ModificationInstruction modL3IPv6Src(IpAddress addr) {
        checkNotNull(addr, "Src l3 IPv6 address cannot be null");
        return new ModIPInstruction(L3SubType.IPV6_SRC, addr);
    }

    /**
     * Creates a L3 IPv6 dst modification.
     *
     * @param addr the IPv6 address to modify to
     * @return a L3 modification
     */
    public static L3ModificationInstruction modL3IPv6Dst(IpAddress addr) {
        checkNotNull(addr, "Dst l3 IPv6 address cannot be null");
        return new ModIPInstruction(L3SubType.IPV6_DST, addr);
    }

    /**
     * Creates a L3 IPv6 Flow Label modification.
     *
     * @param flowLabel the IPv6 flow label to modify to (20 bits)
     * @return a L3 modification
     */
    public static L3ModificationInstruction modL3IPv6FlowLabel(int flowLabel) {
        return new ModIPv6FlowLabelInstruction(flowLabel);
    }

    /**
     * Creates a L3 decrement TTL modification.
     *
     * @return a L3 modification
     */
    public static L3ModificationInstruction decNwTtl() {
        return new ModTtlInstruction(L3SubType.DEC_TTL);
    }

    /**
     * Creates a L3 copy TTL to outer header modification.
     *
     * @return a L3 modification
     */
    public static L3ModificationInstruction copyTtlOut() {
        return new ModTtlInstruction(L3SubType.TTL_OUT);
    }

    /**
     * Creates a L3 copy TTL to inner header modification.
     *
     * @return a L3 modification
     */
    public static L3ModificationInstruction copyTtlIn() {
        return new ModTtlInstruction(L3SubType.TTL_IN);
    }

    /**
     * Creates a L3 ARP IP src modification.
     *
     * @param addr the ip address to modify to
     * @return a L3 modification
     */
    public static L3ModificationInstruction modArpSpa(IpAddress addr) {
        checkNotNull(addr, "Src l3 ARP IP address cannot be null");
        return new ModArpIPInstruction(L3SubType.ARP_SPA, addr);
    }

    /**
     * Creates a l3 ARP Ether src modification.
     *
     * @param addr the mac address to modify to
     * @return a l3 modification
     */
    public static L3ModificationInstruction modArpSha(MacAddress addr) {
        checkNotNull(addr, "Src l3 ARP address cannot be null");
        return new ModArpEthInstruction(L3SubType.ARP_SHA, addr);
    }

    /**
     * Creates a l3 ARP operation modification.
     *
     * @param op the ARP operation to modify to
     * @return a l3 modification
     */
    public static L3ModificationInstruction modL3ArpOp(short op) {
        checkNotNull(op, "Arp operation cannot be null");
        return new ModArpOpInstruction(L3SubType.ARP_OP, op);
    }

    /**
     * Creates a push MPLS header instruction.
     *
     * @return a L2 modification.
     */
    public static Instruction pushMpls() {
        return new L2ModificationInstruction.ModMplsHeaderInstruction(
                L2ModificationInstruction.L2SubType.MPLS_PUSH,
                                          EthType.EtherType.MPLS_UNICAST.ethType());
    }

    /**
     * Creates a pop MPLS header instruction.
     *
     * @return a L2 modification.
     */
    public static Instruction popMpls() {
        return new L2ModificationInstruction.ModMplsHeaderInstruction(
                L2ModificationInstruction.L2SubType.MPLS_POP,
                EthType.EtherType.MPLS_UNICAST.ethType());
    }

    /**
     * Creates a pop MPLS header instruction with a particular ethertype.
     *
     * @param etherType Ethernet type to set
     * @return a L2 modification.
     */
    public static Instruction popMpls(EthType etherType) {
        checkNotNull(etherType, "Ethernet type cannot be null");
        return new L2ModificationInstruction.ModMplsHeaderInstruction(
                L2ModificationInstruction.L2SubType.MPLS_POP, etherType);
    }

    /**
     * Creates a pop VLAN header instruction.
     *
     * @return a L2 modification
     */
    public static Instruction popVlan() {
        return new L2ModificationInstruction.ModVlanHeaderInstruction(
                L2ModificationInstruction.L2SubType.VLAN_POP);
    }

    /**
     * Creates a push VLAN header instruction.
     *
     * @return a L2 modification
     */
    public static Instruction pushVlan() {
        return new L2ModificationInstruction.ModVlanHeaderInstruction(
                L2ModificationInstruction.L2SubType.VLAN_PUSH,
                EthType.EtherType.VLAN.ethType());
    }

    /**
     * Creates a push VLAN header instruction using the supplied Ethernet type.
     *
     * @param ethType the Ethernet type to use
     * @return a L2 modification
     */
    public static Instruction pushVlan(EthType ethType) {
        return new L2ModificationInstruction.ModVlanHeaderInstruction(
                L2ModificationInstruction.L2SubType.VLAN_PUSH,
                ethType);
    }

    /**
     * Sends the packet to the table id.
     *
     * @param tableId flow rule table id
     * @return table type transition instruction
     */
    public static Instruction transition(Integer tableId) {
        checkNotNull(tableId, "Table id cannot be null");
        return new TableTypeTransition(tableId);
    }

    /**
     * Writes metadata to associate with a packet.
     *
     * @param metadata the metadata value to write
     * @param metadataMask the bits to mask for the metadata value
     * @return metadata instruction
     */
    public static Instruction writeMetadata(long metadata, long metadataMask) {
        return new MetadataInstruction(metadata, metadataMask);
    }

    /**
     * Creates a Tunnel ID modification.
     *
     * @param tunnelId the Tunnel ID to modify to
     * @return a L2 modification
     */
    public static L2ModificationInstruction modTunnelId(long tunnelId) {
        checkNotNull(tunnelId, "Tunnel id cannot be null");
        return new L2ModificationInstruction.ModTunnelIdInstruction(tunnelId);
    }

    /**
     * Creates a TCP src modification.
     *
     * @param port the TCP port number to modify to
     * @return a L4 modification
     */
    public static L4ModificationInstruction modTcpSrc(TpPort port) {
       checkNotNull(port, "Src TCP port cannot be null");
       return new ModTransportPortInstruction(L4SubType.TCP_SRC, port);
    }

    /**
     * Creates a TCP dst modification.
     *
     * @param port the TCP port number to modify to
     * @return a L4 modification
     */
    public static L4ModificationInstruction modTcpDst(TpPort port) {
        checkNotNull(port, "Dst TCP port cannot be null");
        return new ModTransportPortInstruction(L4SubType.TCP_DST, port);
    }

    /**
     * Creates a UDP src modification.
     *
     * @param port the UDP port number to modify to
     * @return a L4 modification
     */
    public static L4ModificationInstruction modUdpSrc(TpPort port) {
        checkNotNull(port, "Src UDP port cannot be null");
        return new ModTransportPortInstruction(L4SubType.UDP_SRC, port);
    }

    /**
     * Creates a UDP dst modification.
     *
     * @param port the UDP port number to modify to
     * @return a L4 modification
     */
    public static L4ModificationInstruction modUdpDst(TpPort port) {
        checkNotNull(port, "Dst UDP port cannot be null");
        return new ModTransportPortInstruction(L4SubType.UDP_DST, port);
    }

    /**
     * Creates an extension instruction.
     *
     * @param extension extension instruction
     * @param deviceId device ID
     * @return extension instruction
     */
    public static ExtensionInstructionWrapper extension(ExtensionTreatment extension,
                                                        DeviceId deviceId) {
        checkNotNull(extension, "Extension instruction cannot be null");
        checkNotNull(deviceId, "Device ID cannot be null");
        return new ExtensionInstructionWrapper(extension, deviceId);
    }

    /**
     *  No Action instruction.
     */
    public static final class NoActionInstruction implements Instruction {

        private NoActionInstruction() {}

        @Override
        public Type type() {
            return Type.NOACTION;
        }

        @Override
        public String toString() {
            return type().toString();
        }

        @Override
        public int hashCode() {
            return type().ordinal();
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof NoActionInstruction) {
                return true;
            }
            return false;
        }
    }

    /**
     *  Output Instruction.
     */
    public static final class OutputInstruction implements Instruction {
        private final PortNumber port;

        private OutputInstruction(PortNumber port) {
            this.port = port;
        }

        public PortNumber port() {
            return port;
        }

        @Override
        public Type type() {
            return Type.OUTPUT;
        }

        @Override
        public String toString() {
            return type().toString() + SEPARATOR + port.toString();
        }

        @Override
        public int hashCode() {
            return Objects.hash(type().ordinal(), port);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof OutputInstruction) {
                OutputInstruction that = (OutputInstruction) obj;
                return Objects.equals(port, that.port);

            }
            return false;
        }
    }

    /**
     *  Group Instruction.
     */
    public static final class GroupInstruction implements Instruction {
        private final GroupId groupId;

        private GroupInstruction(GroupId groupId) {
            this.groupId = groupId;
        }

        public GroupId groupId() {
            return groupId;
        }

        @Override
        public Type type() {
            return Type.GROUP;
        }

        @Override
        public String toString() {
            return type().toString() + SEPARATOR + "0x" + Integer.toHexString(groupId.id());
        }

        @Override
        public int hashCode() {
            return Objects.hash(type().ordinal(), groupId);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof GroupInstruction) {
                GroupInstruction that = (GroupInstruction) obj;
                return Objects.equals(groupId, that.groupId);

            }
            return false;
        }
    }

    /**
     *  Set-Queue Instruction.
     */
    public static final class SetQueueInstruction implements Instruction {
        private final long queueId;
        private final PortNumber port;

        private SetQueueInstruction(long queueId) {
            this.queueId = queueId;
            this.port = null;
        }

        private SetQueueInstruction(long queueId, PortNumber port) {
            this.queueId = queueId;
            this.port = port;
        }

        public long queueId() {
            return queueId;
        }

        public PortNumber port() {
            return port;
        }

        @Override
        public Type type() {
            return Type.QUEUE;
        }

        @Override
        public String toString() {
            MoreObjects.ToStringHelper toStringHelper = toStringHelper(type().toString());
            toStringHelper.add("queueId", queueId);

            if (port() != null) {
                toStringHelper.add("port", port);
            }
            return toStringHelper.toString();
        }

        @Override
        public int hashCode() {
            return Objects.hash(type().ordinal(), queueId, port);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof SetQueueInstruction) {
                SetQueueInstruction that = (SetQueueInstruction) obj;
                return Objects.equals(queueId, that.queueId) && Objects.equals(port, that.port);

            }
            return false;
        }
    }

    /**
     * A meter instruction.
     */
    public static final class MeterInstruction implements Instruction {
        private final MeterId meterId;

        private MeterInstruction(MeterId meterId) {
            this.meterId = meterId;
        }

        public MeterId meterId() {
            return meterId;
        }

        @Override
        public Type type() {
            return Type.METER;
        }

        @Override
        public String toString() {
            return type().toString() + SEPARATOR + meterId.id();
        }

        @Override
        public int hashCode() {
            return Objects.hash(type().ordinal(), meterId);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof MeterInstruction) {
                MeterInstruction that = (MeterInstruction) obj;
                return Objects.equals(meterId, that.meterId);

            }
            return false;
        }
    }

    /**
     *  Transition instruction.
     */
    public static class TableTypeTransition implements Instruction {
        private final Integer tableId;

        TableTypeTransition(Integer tableId) {
            this.tableId = tableId;
        }

        @Override
        public Type type() {
            return Type.TABLE;
        }

        public Integer tableId() {
            return this.tableId;
        }

        @Override
        public String toString() {
            return type().toString() + SEPARATOR + this.tableId;
        }

        @Override
        public int hashCode() {
            return Objects.hash(type().ordinal(), tableId);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof TableTypeTransition) {
                TableTypeTransition that = (TableTypeTransition) obj;
                return Objects.equals(tableId, that.tableId);

            }
            return false;
        }
    }

    /**
     *  Metadata instruction.
     */
    public static class MetadataInstruction implements Instruction {
        private final long metadata;
        private final long metadataMask;

        MetadataInstruction(long metadata, long metadataMask) {
            this.metadata = metadata;
            this.metadataMask = metadataMask;
        }

        @Override
        public Type type() {
            return Type.METADATA;
        }

        public long metadata() {
            return this.metadata;
        }

        public long metadataMask() {
            return this.metadataMask;
        }

        @Override
        public String toString() {
            return type().toString() + SEPARATOR +
                    Long.toHexString(this.metadata) + "/" +
                    Long.toHexString(this.metadataMask);
        }

        @Override
        public int hashCode() {
            return Objects.hash(type().ordinal(), metadata, metadataMask);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof MetadataInstruction) {
                MetadataInstruction that = (MetadataInstruction) obj;
                return Objects.equals(metadata, that.metadata) &&
                        Objects.equals(metadataMask, that.metadataMask);

            }
            return false;
        }
    }

    /**
     *  Extension instruction.
     */
    public static class ExtensionInstructionWrapper implements Instruction {
        private final ExtensionTreatment extensionTreatment;
        private final DeviceId deviceId;

        ExtensionInstructionWrapper(ExtensionTreatment extension, DeviceId deviceId) {
            extensionTreatment = extension;
            this.deviceId = deviceId;
        }

        public ExtensionTreatment extensionInstruction() {
            return extensionTreatment;
        }

        public DeviceId deviceId() {
            return deviceId;
        }

        @Override
        public Type type() {
            return Type.EXTENSION;
        }

        @Override
        public String toString() {
            return type().toString() + SEPARATOR + deviceId + "/" + extensionTreatment;
        }

        @Override
        public int hashCode() {
            return Objects.hash(type().ordinal(), extensionTreatment, deviceId);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof ExtensionInstructionWrapper) {
                ExtensionInstructionWrapper that = (ExtensionInstructionWrapper) obj;
                return Objects.equals(extensionTreatment, that.extensionTreatment)
                        && Objects.equals(deviceId, that.deviceId);

            }
            return false;
        }
    }

}


