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

import java.util.Objects;

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

    private static final String SEPARATOR = ":";

    /**
     * Represents the type of traffic treatment.
     */
    public enum L3SubType {
        /**
         * IPv4 src modification.
         */
        IPV4_SRC,

        /**
         * IPv4 dst modification.
         */
        IPV4_DST,

        /**
         * IPv6 src modification.
         */
        IPV6_SRC,

        /**
         * IPv6 dst modification.
         */
        IPV6_DST,

        /**
         * IPv6 flow label modification.
         */
        IPV6_FLABEL,

        /**
         * Decrement TTL.
         */
        DEC_TTL,

        /**
         * Copy TTL out.
         */
        TTL_OUT,

        /**
         * Copy TTL in.
         */
        TTL_IN,

        /**
         * ARP IP src modification.
         */
        ARP_SPA,

        /**
         * ARP Ether src modification.
         */
        ARP_SHA,

        /**
         * Arp operation modification.
         */
        ARP_OP
    }

    /**
     * Returns the subtype of the modification instruction.
     * @return type of instruction
     */
    public abstract L3SubType subtype();

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

    /**
     * Represents a L3 src/dst modification instruction.
     */
    public static final class ModIPInstruction extends L3ModificationInstruction {

        private final L3SubType subtype;
        private final IpAddress ip;

        ModIPInstruction(L3SubType subType, IpAddress addr) {

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

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

        public IpAddress ip() {
            return this.ip;
        }

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

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

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

    /**
     * Represents a L3 ARP IP src/dst modification instruction.
     */
    public static final class ModArpIPInstruction extends L3ModificationInstruction {

        private final L3SubType subtype;
        private final IpAddress ip;

        ModArpIPInstruction(L3SubType subType, IpAddress addr) {

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

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

        public IpAddress ip() {
            return this.ip;
        }

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

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

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

    /**
     * Represents a L3 ARP Ether src/dst modification instruction.
     */
    public static final class ModArpEthInstruction extends L3ModificationInstruction {

        private final L3SubType subtype;
        private final MacAddress mac;

        ModArpEthInstruction(L3SubType subType, MacAddress addr) {

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

        @Override
        public L3SubType 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 ModArpEthInstruction) {
                ModArpEthInstruction that = (ModArpEthInstruction) obj;
                return  Objects.equals(mac, that.mac) &&
                        Objects.equals(this.subtype(), that.subtype());
            }
            return false;
        }
    }

    /**
     * Represents a L3 ARP operation modification instruction.
     */
    public static final class ModArpOpInstruction extends L3ModificationInstruction {

        private final L3SubType subtype;
        private final short op;

        ModArpOpInstruction(L3SubType subType, short op) {

            this.subtype = subType;
            this.op = op;
        }

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

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

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

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

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

    /**
     * Represents a L3 IPv6 Flow Label (RFC 6437) modification instruction
     * (20 bits unsigned integer).
     */
    public static final class ModIPv6FlowLabelInstruction
        extends L3ModificationInstruction {
        private static final int MASK = 0xfffff;
        private final int flowLabel;            // IPv6 flow label: 20 bits

        /**
         * Creates a new flow mod instruction.
         *
         * @param flowLabel the IPv6 flow label to set in the treatment (20 bits)
         */
        ModIPv6FlowLabelInstruction(int flowLabel) {
            this.flowLabel = flowLabel & MASK;
        }

        @Override
        public L3SubType subtype() {
            return L3SubType.IPV6_FLABEL;
        }

        /**
         * Gets the IPv6 flow label to set in the treatment.
         *
         * @return the IPv6 flow label to set in the treatment (20 bits)
         */
        public int flowLabel() {
            return this.flowLabel;
        }

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

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

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

    /**
     * Represents a L3 TTL modification instruction.
     */
    public static final class ModTtlInstruction extends L3ModificationInstruction {

        private final L3SubType subtype;

        ModTtlInstruction(L3SubType subtype) {
            this.subtype = subtype;
        }

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

        @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 ModTtlInstruction) {
                ModTtlInstruction that = (ModTtlInstruction) obj;
                return  Objects.equals(this.subtype(), that.subtype());
            }
            return false;
        }
    }
}
