package net.floodlightcontroller.util;

import java.util.EnumSet;
import java.util.Set;

/**
 * A utility class to convert between integer based bitmaps for (OpenFlow)
 * flags and Enum and EnumSet based representations.
 *
 * The enum used to represent individual flags needs to implement the
 * BitmapableEnum interface.
 *
 * Example:
 * {@code
 *   int bitmap = 0x11; // OFPPC_PORT_DOWN | OFPPC_NO_STP
 *   EnumSet<OFPortConfig> s = toEnumSet(OFPortConfig.class, bitmap);
 *   // s will contain OFPPC_PORT_DOWN and OFPPC_NO_STP
 * }
 *
 * {@code
 *    EnumSet<OFPortConfig> s = EnumSet.of(OFPPC_NO_STP, OFPPC_PORT_DOWN);
 *    int bitmap = toBitmap(s); // returns 0x11
 * }
 * @author gregor
 *
 */
public class EnumBitmaps {
    /**
     * Enums used to represent individual flags needs to implement this
     * interface
     */
    public interface BitmapableEnum {
        /** Return the value in the bitmap that the enum constant represents.
         * The returned value must have only a single bit set. E.g.,1<<3
         */
        int getValue();
    }

    /**
     * Convert an integer bitmap to an EnumSet.
     *
     * See class description for example
     * @param type The Enum class to use. Must implement BitmapableEnum
     * @param bitmap The integer bitmap
     * @return A newly allocated EnumSet representing the bits set in the
     * bitmap
     * @throws NullPointerException if type is null
     * @throws IllegalArgumentException if any enum constant from type has
     * more than one bit set.
     * @throws IllegalArgumentException if the bitmap has any bits set not
     * represented by an enum constant.
     */
    public static <E extends Enum<E> & BitmapableEnum>
            EnumSet<E> toEnumSet(Class<E> type, int bitmap) {
        if (type == null)
            throw new NullPointerException("Given enum type must not be null");
        EnumSet<E> s = EnumSet.noneOf(type);
        // allSetBitmap will eventually have all valid bits for the given
        // type set.
        int allSetBitmap = 0;
        for (E element: type.getEnumConstants()) {
            if (Integer.bitCount(element.getValue()) != 1) {
                String msg = String.format("The %s (%x) constant of the " +
                        "enum %s is supposed to represent a bitmap entry but " +
                        "has more than one bit set.",
                        element.toString(), element.getValue(), type.getName());
                throw new IllegalArgumentException(msg);
            }
            allSetBitmap |= element.getValue();
            if ((bitmap & element.getValue()) != 0)
                s.add(element);
        }
        if (((~allSetBitmap) & bitmap) != 0) {
            // check if only valid flags are set in the given bitmap
            String msg = String.format("The bitmap %x for enum %s has " +
                    "bits set that are presented by any enum constant",
                    bitmap, type.getName());
            throw new IllegalArgumentException(msg);
        }
        return s;
    }

    /**
     * Return the bitmap mask with all possible bits set. E.g., If a bitmap
     * has the individual flags 0x1, 0x2, and 0x8 (note the missing 0x4) then
     * the mask will be 0xb (1011 binary)
     *
     * @param type The Enum class to use. Must implement BitmapableEnum
     * @throws NullPointerException if type is null
     * @throws IllegalArgumentException if any enum constant from type has
     * more than one bit set
     * @return an integer with all possible bits for the given bitmap enum
     * type set.
     */
    public static <E extends Enum<E> & BitmapableEnum>
            int getMask(Class<E> type) {
        if (type == null)
            throw new NullPointerException("Given enum type must not be null");
        // allSetBitmap will eventually have all valid bits for the given
        // type set.
        int allSetBitmap = 0;
        for (E element: type.getEnumConstants()) {
            if (Integer.bitCount(element.getValue()) != 1) {
                String msg = String.format("The %s (%x) constant of the " +
                        "enum %s is supposed to represent a bitmap entry but " +
                        "has more than one bit set.",
                        element.toString(), element.getValue(), type.getName());
                throw new IllegalArgumentException(msg);
            }
            allSetBitmap |= element.getValue();
        }
        return allSetBitmap;
    }

    /**
     * Convert the given EnumSet to the integer bitmap representation
     * @param set The EnumSet to convert. The enum must implement
     * BitmapableEnum
     * @return the integer bitmap
     * @throws IllegalArgumentException if an enum constant from the set (!) has
     * more than one bit set
     * @throws NullPointerException if the set is null
     */
    public static <E extends Enum<E> & BitmapableEnum>
            int toBitmap(Set<E> set) {
        if (set == null)
            throw new NullPointerException("Given set must not be null");
        int bitmap = 0;
        for (E element: set) {
            if (Integer.bitCount(element.getValue()) != 1) {
                String msg = String.format("The %s (%x) constant in the set " +
                        "is supposed to represent a bitmap entry but " +
                        "has more than one bit set.",
                        element.toString(), element.getValue());
                throw new IllegalArgumentException(msg);
            }
            bitmap |= element.getValue();
        }
        return bitmap;
    }
}
