/**
 *    Copyright 2013, Big Switch Networks, Inc.
 *
 *    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.projectfloodlight.openflow.protocol;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.google.common.base.Joiner;

/**
 * a more user friendly representation of the wildcards bits in an OpenFlow
 * match. The Wildcards object is
 * <ul>
 * <li>immutable (i.e., threadsafe)</li>
 * <li>instance managed (don't instantiate it yourself), instead call "of"</li>
 * <ul>
 * <p>
 * You can construct a Wildcard object from either its integer representation
 * </p>
 * <code>
 *    Wildcard.of(0x3820e0);
 *  </code>
 * <p>
 * Or start with either an empty or full wildcard, and select/unselect foo.
 * </p>
 * <code>
 *  Wildcard w = Wildcards.NONE
 *                .set(Flag.DL_SRC, Flag. DL_DST, Flag.DL_VLAN_PCP)
 *                .setNwDstMask(8)
 *                .setNwSrcMask(8);
 *  </code>
 * <p>
 * <b>Remember:</b> Wildcards objects are immutable. set... operations have
 * <b>NO EFFECT</b> on the current wildcard object. You HAVE to use the returned
 * changed object.
 * </p>
 *
 * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
 */
public class Wildcards {
    public class OFWildcardFlags {
        final public static int OFPFW_ALL = ((1 << 22) - 1);

        final public static int OFPFW_IN_PORT = 1 << 0; /* Switch input port. */
        final public static int OFPFW_DL_VLAN = 1 << 1; /* VLAN id. */
        final public static int OFPFW_DL_SRC = 1 << 2; /* Ethernet source address. */
        final public static int OFPFW_DL_DST = 1 << 3; /*
                                                        * Ethernet destination
                                                        * address.
                                                        */
        final public static int OFPFW_DL_TYPE = 1 << 4; /* Ethernet frame type. */
        final public static int OFPFW_NW_PROTO = 1 << 5; /* IP protocol. */
        final public static int OFPFW_TP_SRC = 1 << 6; /* TCP/UDP source port. */
        final public static int OFPFW_TP_DST = 1 << 7; /* TCP/UDP destination port. */

        /*
         * IP source address wildcard bit count. 0 is exact match, 1 ignores the
         * LSB, 2 ignores the 2 least-significant bits, ..., 32 and higher wildcard
         * the entire field. This is the *opposite* of the usual convention where
         * e.g. /24 indicates that 8 bits (not 24 bits) are wildcarded.
         */
        final public static int OFPFW_NW_SRC_SHIFT = 8;
        final public static int OFPFW_NW_SRC_BITS = 6;
        final public static int OFPFW_NW_SRC_MASK = ((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT;
        final public static int OFPFW_NW_SRC_ALL = 32 << OFPFW_NW_SRC_SHIFT;

        /* IP destination address wildcard bit count. Same format as source. */
        final public static int OFPFW_NW_DST_SHIFT = 14;
        final public static int OFPFW_NW_DST_BITS = 6;
        final public static int OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT;
        final public static int OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT;

        final public static int OFPFW_DL_VLAN_PCP = 1 << 20; /* VLAN priority. */
        final public static int OFPFW_NW_TOS = 1 << 21; /*
                                                         * IP ToS (DSCP field, 6
                                                         * bits).
                                                         */

        final public static int OFPFW_ALL_SANITIZED = (((1 << 22) - 1)
                                                       & ~OFPFW_NW_SRC_MASK & ~OFPFW_NW_DST_MASK)
                                                      | OFPFW_NW_SRC_ALL
                                                      | OFPFW_NW_DST_ALL;


    }

    public final static Wildcards FULL = new Wildcards(OFWildcardFlags.OFPFW_ALL_SANITIZED);
    private static final int FULL_INT = FULL.getInt();

    public final static Wildcards EXACT = new Wildcards(0);

    // floodlight common case: matches on inport + l2
    public final static int INT_INPORT_L2_MATCH = 0x3820e0;
    public final static Wildcards INPORT_L2_MATCH = new Wildcards(
            INT_INPORT_L2_MATCH);

    /**
     * enum type for the binary flags that can be set in the wildcards field of
     * an OFWildcardFlags. Replaces the unwieldy c-ish int constants in OFWildcardFlags.
     */
    public static enum Flag {
        IN_PORT(OFWildcardFlags.OFPFW_IN_PORT),  /* Switch input port. */
        DL_VLAN(OFWildcardFlags.OFPFW_DL_VLAN), /* VLAN id. */
        DL_SRC(OFWildcardFlags.OFPFW_DL_SRC), /* Ethernet source address. */
        DL_DST(OFWildcardFlags.OFPFW_DL_DST), /* Ethernet destination addr */
        DL_TYPE(OFWildcardFlags.OFPFW_DL_TYPE), /* Ethernet frame type. */
        NW_PROTO(OFWildcardFlags.OFPFW_NW_PROTO), /* IP protocol. */
        TP_SRC(OFWildcardFlags.OFPFW_TP_SRC), /* TCP/UDP source port. */
        TP_DST(OFWildcardFlags.OFPFW_TP_DST), /* TCP/UDP destination port. */
        DL_VLAN_PCP(OFWildcardFlags.OFPFW_DL_VLAN_PCP), /* VLAN priority. */
        NW_SRC(-1) { /*
                      * virtual NW_SRC flag => translates to the strange 6 bits
                      * in the header
                      */
            @Override
            boolean isBolean() {
                return false;
            }

            @Override
            int getInt(int flags) {
                return ((flags & OFWildcardFlags.OFPFW_NW_SRC_MASK) >> OFWildcardFlags.OFPFW_NW_SRC_SHIFT);
            }

            @Override
            int setInt(int flags, int srcMask) {
                return (flags & ~OFWildcardFlags.OFPFW_NW_SRC_MASK) | (srcMask << OFWildcardFlags.OFPFW_NW_SRC_SHIFT);
            }

            @Override
            int wildcard(int flags) {
                return flags & ~OFWildcardFlags.OFPFW_NW_SRC_MASK;
            }

            @Override
            int matchOn(int flags) {
                return flags | OFWildcardFlags.OFPFW_NW_SRC_ALL;
            }

            @Override
            boolean isPartiallyOn(int flags) {
                int intValue = getInt(flags);
                return intValue > 0 && intValue < 32;
            }

            @Override
            boolean isFullyOn(int flags) {
                return getInt(flags) >= 32;
            }

        },
        NW_DST(-1) { /*
                      * virtual NW_SRC flag => translates to the strange 6 bits
                      * in the header
                      */
            @Override
            boolean isBolean() {
                return false;
            }

            @Override
            int getInt(int flags) {
                return ((flags & OFWildcardFlags.OFPFW_NW_DST_MASK) >> OFWildcardFlags.OFPFW_NW_DST_SHIFT);
            }

            @Override
            int setInt(int flags, int srcMask) {
                return (flags & ~OFWildcardFlags.OFPFW_NW_DST_MASK) | (srcMask << OFWildcardFlags.OFPFW_NW_DST_SHIFT);
            }

            @Override
            int wildcard(int flags) {
                return flags & ~OFWildcardFlags.OFPFW_NW_DST_MASK;
            }

            @Override
            int matchOn(int flags) {
                return flags | OFWildcardFlags.OFPFW_NW_DST_ALL;
            }

            @Override
            boolean isFullyOn(int flags) {
                return getInt(flags) >= 32;
            }
        },
        NW_TOS(OFWildcardFlags.OFPFW_NW_TOS); /* IP ToS (DSCP field, 6 bits). */

        final int bitPosition;

        Flag(int bitPosition) {
            this.bitPosition = bitPosition;
        }

        /**
         * @return a modified OF-1.0 flags field with this flag cleared (match
         *         on this field)
         */
        int matchOn(int flags) {
            return flags & ~this.bitPosition;
        }

        /**
         * @return a modified OF-1.0 flags field with this flag set (wildcard
         *         this field)
         */
        int wildcard(int flags) {
            return flags | this.bitPosition;
        }

        /**
         * @return true iff this is a true boolean flag that can either be off
         *         or on.True in OF-1.0 for all fields except NW_SRC and NW_DST
         */
        boolean isBolean() {
            return false;
        }

        /**
         * @return true iff this wildcard field is currently 'partially on'.
         *         Always false for true Boolean Flags. Can be true in OF-1.0
         *         for NW_SRC, NW_DST.
         */
        boolean isPartiallyOn(int flags) {
            return false;
        }

        /**
         * @return true iff this wildcard field currently fully on (fully
         *         wildcarded). Equivalent to the boolean flag being set in the
         *         bitmask for bit flags, and to the wildcarded bit length set
         *         to >=32 for NW_SRC and NW_DST
         * @param flags
         * @return
         */
        boolean isFullyOn(int flags) {
            return (flags & this.bitPosition) != 0;
        }

        /**
         * set the integer representation of this flag. only for NW_SRC and
         * NW_DST
         */
        int setInt(int flags, int srcMask) {
            throw new UnsupportedOperationException();
        }

        /**
         * set the integer representation of this flag. only for NW_SRC and
         * NW_DST
         */
        int getInt(int flags) {
            throw new UnsupportedOperationException();
        }


    }

    private final int flags;

    /** private constructor. use Wildcard.of() instead */
    private Wildcards(int flags) {
        this.flags = flags;
    }

    /**
     * return a wildcard object matching the given int flags. May reuse / cache
     * frequently used wildcard instances. Don't rely on it though (use equals
     * not ==).
     *
     * @param flags
     * @return
     */
    public static Wildcards of(int paramFlags) {
        int flags = paramFlags; //sanitizeInt(paramFlags);
        switch(flags) {
            case 0x0000:
                return EXACT;
            case OFWildcardFlags.OFPFW_ALL_SANITIZED:
                return FULL;
            case INT_INPORT_L2_MATCH:
                return INPORT_L2_MATCH;
            default:
                return new Wildcards(flags);
        }
    }

    /** convience method return a wildcard for exactly one set flag */
    public static Wildcards of(Wildcards.Flag setFlag) {
        return Wildcards.of(setFlag.wildcard(0));
    }

    /** convience method return a wildcard for exactly two set flags */
    public static Wildcards of(Wildcards.Flag setFlag, Wildcards.Flag setFlag2) {
        return Wildcards.of(setFlag.wildcard(setFlag2.wildcard(0)));
    }

    /** convience method return a wildcard for an arbitrary number of set flags */
    public static Wildcards of(Wildcards.Flag... setFlags) {
        int flags = 0;
        for (Wildcards.Flag flag : setFlags)
            flags = flag.wildcard(0);
        return Wildcards.of(flags);
    }

    /** convience method return a wildcards for ofmatches that match on one flag */
    public static Wildcards ofMatches(Wildcards.Flag setFlag) {
        return Wildcards.of(setFlag.matchOn(FULL_INT));
    }

    /**
     * convience method return a wildcard for for an ofmatch that match on two
     * flags
     */
    public static Wildcards ofMatches(Wildcards.Flag setFlag, Wildcards.Flag setFlag2) {
        return Wildcards.of(setFlag.matchOn(setFlag2.matchOn(FULL_INT)));
    }

    /**
     * convience method return a wildcard for an ofmatch that amtch on an
     * arbitrary number of set flags
     */
    public static Wildcards ofMatches(Wildcards.Flag... setFlags) {
        int flags = FULL_INT;
        for (Wildcards.Flag flag : setFlags)
           flags = flag.matchOn(flags);
        return Wildcards.of(flags);
    }

    public static Wildcards ofMatches(Set<Wildcards.Flag> wSet) {
        int flags = FULL_INT;
        for (Wildcards.Flag flag : wSet)
           flags = flag.matchOn(flags);
        return Wildcards.of(flags);
    }

    /**
     * return a Wildcards object that has the given flags set
     * <p>
     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
     * unmodified. </b>
     */
    public Wildcards wildcard(Wildcards.Flag flag) {
        int flags = flag.wildcard(this.flags);
        if (flags == this.flags)
            return this;
        else
            return new Wildcards(flags);
    }

    /**
     * return a Wildcards object that has the given flags set
     * <p>
     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
     * unmodified. </b>
     */
    public Wildcards wildcard(Wildcards.Flag flag, Wildcards.Flag flag2) {
        int flags = flag.wildcard(flag2.wildcard(this.flags));
        if (flags == this.flags)
            return this;
        else
            return new Wildcards(flags);
    }

    /**
     * return a Wildcards object that has the given flags wildcarded
     * <p>
     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
     * unmodified. </b>
     */
    public Wildcards wildcard(Wildcards.Flag... setFlags) {
        int flags = this.flags;
        for (Wildcards.Flag flag : setFlags)
            flags = flag.wildcard(flags);
        if (flags == this.flags)
            return this;
        else
            return new Wildcards(flags);
    }

    /**
     * return a Wildcards object that matches on exactly the given flag
     * <p>
     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
     * unmodified. </b>
     */
    public Wildcards matchOn(Wildcards.Flag flag) {
        int flags = flag.matchOn(this.flags);
        if (flags == this.flags)
            return this;
        else
            return new Wildcards(flags);
    }

    /**
     * return a Wildcards object that matches on exactly the given flags
     * <p>
     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
     * unmodified. </b>
     */
    public Wildcards matchOn(Wildcards.Flag flag, Wildcards.Flag flag2) {
        int flags = flag.matchOn(flag2.matchOn(this.flags));
        if (flags == this.flags)
            return this;
        else
            return new Wildcards(flags);
    }

    /**
     * return a Wildcards object that matches on exactly the given flags
     * <p>
     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
     * unmodified. </b>
     */
    public Wildcards matchOn(Wildcards.Flag... setFlags) {
        int flags = this.flags;
        for (Wildcards.Flag flag : setFlags)
            flags = flag.matchOn(flags);
        if (flags == this.flags)
            return this;
        else
            return new Wildcards(flags);
    }

    /**
     * return the nw src mask in normal CIDR style, e.g., 8 means x.x.x.x/8
     * means 8 bits wildcarded
     */
    public int getNwSrcMask() {
        return Math.max(0, 32 - Flag.NW_SRC.getInt(flags));
    }

    /**
     * return the nw dst mask in normal CIDR style, e.g., 8 means x.x.x.x/8
     * means 8 bits wildcarded
     */
    public int getNwDstMask() {
        return Math.max(0, 32 - Flag.NW_DST.getInt(flags));
    }

    /**
     * return a Wildcard object that has the given nwSrcCidrMask set.
     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
     * unmodified. </b>
     *
     * @param srcCidrMask
     *            source mask to set in <b>normal CIDR notation</b>, i.e., 8
     *            means x.x.x.x/8
     * @return a modified object
     */
    public Wildcards withNwSrcMask(int srcCidrMask) {
        int flags = Flag.NW_SRC.setInt(this.flags, Math.max(0, 32 - srcCidrMask));
        if (flags == this.flags)
            return this;
        else
            return new Wildcards(flags);
    }

    /**
     * return a Wildcard object that has the given nwDstCidrMask set.
     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
     * unmodified. </b>
     *
     * @param dstCidrMask
     *            dest mask to set in <b>normal CIDR notation</b>, i.e., 8 means
     *            x.x.x.x/8
     * @return a modified object
     */
    public Wildcards withNwDstMask(int dstCidrMask) {
        int flags = Flag.NW_DST.setInt(this.flags, Math.max(0, 32 - dstCidrMask));
        if (flags == this.flags)
            return this;
        else
            return new Wildcards(flags);
    }

    /**
     * return a Wildcard object that is inverted to this wildcard object.
     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
     * unmodified. </b>
     * @return a modified object
     */
    public Wildcards inverted() {
        return Wildcards.of(flags ^ OFWildcardFlags.OFPFW_ALL_SANITIZED);
    }

    public boolean isWildcarded(Flag flag) {
        return flag.isFullyOn(flags);
    }

    /**
     * return all wildcard flags that are fully wildcarded as an EnumSet. Do not
     * modify. Note: some flags (like NW_SRC and NW_DST) that are partially
     * wildcarded are not returned in this set.
     *
     * @return the EnumSet of wildcards
     */
    public EnumSet<Wildcards.Flag> getWildcardedFlags() {
        EnumSet<Wildcards.Flag> res = EnumSet.noneOf(Wildcards.Flag.class);
        for (Wildcards.Flag flag : Flag.values()) {
            if (flag.isFullyOn(flags)) {
                res.add(flag);
            }
        }
        return res;
    }

    /** return the OpenFlow 'wire' integer representation of these wildcards */
    public int getInt() {
        return flags;
    }

    /**
     * return the OpenFlow 'wire' integer representation of these wildcards.
     * Sanitize nw_src and nw_dst to be max. 32 (values > 32 are technically
     * possible, but don't make semantic sense)
     */
    public static int sanitizeInt(int flags) {
        if (((flags & OFWildcardFlags.OFPFW_NW_SRC_MASK) >> OFWildcardFlags.OFPFW_NW_SRC_SHIFT) > 32) {
            flags = (flags & ~OFWildcardFlags.OFPFW_NW_SRC_MASK) | OFWildcardFlags.OFPFW_NW_SRC_ALL;
        }
        if (((flags & OFWildcardFlags.OFPFW_NW_DST_MASK) >> OFWildcardFlags.OFPFW_NW_DST_SHIFT) > 32) {
            flags = (flags & ~OFWildcardFlags.OFPFW_NW_DST_MASK) | OFWildcardFlags.OFPFW_NW_DST_ALL;
        }
        return flags;
    }

    /**
     * is this a wildcard set that has all flags set + and full (/0) nw_src and
     * nw_dst wildcarding ?
     */
    public boolean isFull() {
        return flags == OFWildcardFlags.OFPFW_ALL || flags == OFWildcardFlags.OFPFW_ALL_SANITIZED;
    }

    /** is this a wildcard of an exact match */
    public boolean isExact() {
        return flags == 0;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + flags;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Wildcards other = (Wildcards) obj;
        if (flags != other.flags)
            return false;
        return true;
    }

    private final static Joiner pipeJoiner = Joiner.on("|");

    @Override
    public String toString() {
        List<String> res = new ArrayList<String>();
        for (Wildcards.Flag flag : Flag.values()) {
            if (flag.isFullyOn(flags)) {
                res.add(flag.name().toLowerCase());
            }
        }

        if (Flag.NW_SRC.isPartiallyOn(flags)) {
            res.add("nw_src(/" + getNwSrcMask() + ")");
        }

        if (Flag.NW_DST.isPartiallyOn(flags)) {
            res.add("nw_dst(/" + getNwDstMask() + ")");
        }

        return pipeJoiner.join(res);
    }

    private final static Joiner commaJoiner = Joiner.on(", ");

    /** a Java expression that constructs 'this' wildcards set */
    public String toJava() {
        if(isFull()) {
            return "Wildcards.FULL";
        } else  if (isExact()){
            return "Wildcards.EXACT";
        }

        StringBuilder b = new StringBuilder();

        EnumSet<Flag> myFlags = getWildcardedFlags();
        if (myFlags.size() < 3) {
            // default to start with empty
            b.append("Wildcards.of("
                     + commaJoiner.join(prefix("Flag.", myFlags.iterator())) + ")");
        } else {
            // too many - start with full

            EnumSet<Flag> invFlags = inverted().getWildcardedFlags();
            b.append("Wildcards.ofMatches("
                     + commaJoiner.join(prefix("Flag.", invFlags.iterator())) + ")");
        }
        if (Flag.NW_SRC.isPartiallyOn(flags)) {
            b.append(".setNwSrcMask(" + getNwSrcMask() + ")");
        }
        if (Flag.NW_DST.isPartiallyOn(flags)) {
            b.append(".setNwDstMask(" + getNwDstMask() + ")");
        }
        return b.toString();
    }

    private Iterator<String> prefix(final String prefix, final Iterator<?> i) {
        return new Iterator<String>() {

            @Override
            public boolean hasNext() {
                return i.hasNext();
            }

            @Override
            public String next() {
                Object next = i.next();
                return next == null ? null : prefix + next.toString();
            }

            @Override
            public void remove() {
                i.remove();
            }
        };
    }


}