/*
 * 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 org.onlab.packet.EthType;
import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.VlanId;

import java.util.Objects;

/**
 * Abstraction of a single traffic treatment step.
 */
public abstract class L2ModificationInstruction implements Instruction {

    private static final String SEPARATOR = ":";

    /**
     * Represents the type of traffic treatment.
     */
    public enum L2SubType {
        /**
         * Ether src modification.
         */
        ETH_SRC,

        /**
         * Ether dst modification.
         */
        ETH_DST,

        /**
         * VLAN id modification.
         */
        VLAN_ID,

        /**
         * VLAN priority modification.
         */
        VLAN_PCP,

        /**
         * MPLS Label modification.
         */
        MPLS_LABEL,

        /**
         * MPLS Push modification.
         */
        MPLS_PUSH,

        /**
         * MPLS Pop modification.
         */
        MPLS_POP,

        /**
         * MPLS TTL modification.
         */
        DEC_MPLS_TTL,

        /**
         * VLAN Pop modification.
         */
        VLAN_POP,

        /**
         * VLAN Push modification.
         */
        VLAN_PUSH,

        /**
         * Tunnel id modification.
         */
        TUNNEL_ID,

        /**
         * MPLS BOS instruction.
         */
        MPLS_BOS
    }

    public abstract L2SubType subtype();

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

    /**
     * Represents a L2 src/dst modification instruction.
     */
    public static final class ModEtherInstruction extends L2ModificationInstruction {

        private final L2SubType subtype;
        private final MacAddress mac;

        ModEtherInstruction(L2SubType subType, MacAddress addr) {

            this.subtype = subType;
            this.mac = addr;
        }

        @Override
        public L2SubType subtype() {
            return this.subtype;
        }

        public MacAddress mac() {
            return this.mac;
        }

        @Override
        public String toString() {
            return subtype().toString() + SEPARATOR + mac;
        }

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

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof ModEtherInstruction) {
                ModEtherInstruction that = (ModEtherInstruction) obj;
                return  Objects.equals(mac, that.mac) &&
                        Objects.equals(subtype, that.subtype);
            }
            return false;
        }
    }

    /**
     * Represents a MPLS header modification instruction.
     */
    public static final class ModMplsHeaderInstruction extends L2ModificationInstruction {

        private final L2SubType subtype;
        private final EthType ethernetType; // Ethernet type value: 16 bits

        ModMplsHeaderInstruction(L2SubType subType, EthType ethernetType) {
            this.subtype = subType;
            this.ethernetType = ethernetType;
        }

        public EthType ethernetType() {
            return ethernetType;
        }

        @Override
        public L2SubType subtype() {
            return subtype;
        }

        @Override
        public String toString() {
            return subtype().toString() + SEPARATOR + ethernetType;
        }

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

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof ModMplsHeaderInstruction) {
                ModMplsHeaderInstruction that = (ModMplsHeaderInstruction) obj;
                return Objects.equals(subtype, that.subtype) &&
                       Objects.equals(this.ethernetType, that.ethernetType);
            }
            return false;
        }
    }

    /**
     * Represents a VLAN id modification instruction.
     */
    public static final class ModVlanIdInstruction extends L2ModificationInstruction {

        private final VlanId vlanId;

        ModVlanIdInstruction(VlanId vlanId) {
            this.vlanId = vlanId;
        }

        @Override
        public L2SubType subtype() {
            return L2SubType.VLAN_ID;
        }

        public VlanId vlanId() {
            return this.vlanId;
        }

        @Override
        public String toString() {
            return subtype().toString() + SEPARATOR + vlanId;
        }

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

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

    /**
     * Represents a VLAN PCP modification instruction.
     */
    public static final class ModVlanPcpInstruction extends L2ModificationInstruction {

        private static final byte MASK = 0x7;
        private final byte vlanPcp;

        ModVlanPcpInstruction(byte vlanPcp) {
            this.vlanPcp = (byte) (vlanPcp & MASK);
        }

        @Override
        public L2SubType subtype() {
            return L2SubType.VLAN_PCP;
        }

        public byte vlanPcp() {
            return this.vlanPcp;
        }

        @Override
        public String toString() {
            return subtype().toString() + SEPARATOR + Long.toHexString(vlanPcp);
        }

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

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

    /**
     * Represents a VLAN Header modification instruction.
     */
    public static final class ModVlanHeaderInstruction extends L2ModificationInstruction {

        private final L2SubType subtype;
        private EthType ethernetType; // Ethernet type value: 16 bits

        ModVlanHeaderInstruction(L2SubType subType, EthType ethernetType) {
            this.subtype = subType;
            this.ethernetType = ethernetType;
        }

        ModVlanHeaderInstruction(L2SubType subType) {
            this(subType, EthType.EtherType.UNKNOWN.ethType());
        }

        public EthType ethernetType() {
            return ethernetType;
        }

        @Override
        public L2SubType subtype() {
            return subtype;
        }

        @Override
        public String toString() {
            // etherType is not specified in VLAN_POP case. Ignore it.
            return subtype().equals(L2SubType.VLAN_POP) ?
                    subtype().toString() :
                    subtype().toString() + SEPARATOR + ethernetType;
        }

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

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof ModVlanHeaderInstruction) {
                ModVlanHeaderInstruction that = (ModVlanHeaderInstruction) obj;
                return Objects.equals(subtype, that.subtype) &&
                        Objects.equals(this.ethernetType, that.ethernetType);
            }
            return false;
        }
    }

    /**
     * Represents a MPLS label modification.
     */
    public static final class ModMplsLabelInstruction
            extends L2ModificationInstruction {

        private final MplsLabel mplsLabel;

        ModMplsLabelInstruction(MplsLabel mplsLabel) {
            this.mplsLabel = mplsLabel;
        }

        public MplsLabel label() {
            return mplsLabel;
        }

        /**
         * Extracts the MPLS label from the instruction.
         *
         * @return MPLS label
         * @deprecated deprecated in 1.5.0 Falcon
         */
        @Deprecated
        public MplsLabel mplsLabel() {
            return label();
        }

        @Override
        public L2SubType subtype() {
            return L2SubType.MPLS_LABEL;
        }

        @Override
        public String toString() {
            return subtype().toString() + SEPARATOR + mplsLabel;
        }

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

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

    /**
     * Represents a MPLS BOS modification.
     */
    public static final class ModMplsBosInstruction
            extends L2ModificationInstruction {

        private final boolean mplsBos;

        ModMplsBosInstruction(boolean mplsBos) {
            this.mplsBos = mplsBos;
        }

        public boolean mplsBos() {
            return mplsBos;
        }

        @Override
        public L2SubType subtype() {
            return L2SubType.MPLS_BOS;
        }

        @Override
        public String toString() {
            return subtype().toString() + SEPARATOR + mplsBos;
        }

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

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

    /**
     * Represents a MPLS TTL modification.
     */
    public static final class ModMplsTtlInstruction
            extends L2ModificationInstruction {

        ModMplsTtlInstruction() {
        }

        @Override
        public L2SubType subtype() {
            return L2SubType.DEC_MPLS_TTL;
        }

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

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

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

    /**
     * Represents a Tunnel id modification.
     */
    public static final class ModTunnelIdInstruction
            extends L2ModificationInstruction {

        private final long tunnelId;

        ModTunnelIdInstruction(long tunnelId) {
            this.tunnelId = tunnelId;
        }

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

        @Override
        public L2SubType subtype() {
            return L2SubType.TUNNEL_ID;
        }

        @Override
        public String toString() {
            return subtype().toString() + SEPARATOR + Long.toHexString(tunnelId);
        }

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

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