package net.onrc.onos.core.util;

import net.floodlightcontroller.util.MACAddress;

import org.codehaus.jackson.annotate.JsonProperty;

/**
 * The class representing a single Flow Entry action.
 * <p/>
 * A Flow Entry action that needs to be applied to each packet.
 * Note that it contains only a single action. Multiple actions are
 * listed in a list inside @ref FlowEntryActions.
 */
public class FlowEntryAction {
    /**
     * Special action values.
     * <p/>
     * Those values are taken as-is from the OpenFlow-v1.0.0 specification
     * (pp 21-22).
     */
    public enum ActionValues {
        ACTION_OUTPUT((short) 0x0),    // Output to switch port
        ACTION_SET_VLAN_VID((short) 0x1),    // Set the 802.1q VLAN id
        ACTION_SET_VLAN_PCP((short) 0x2),    // Set the 802.1q priority
        ACTION_STRIP_VLAN((short) 0x3),    // Strip the 802.1q header
        ACTION_SET_DL_SRC((short) 0x4),    // Ethernet source address
        ACTION_SET_DL_DST((short) 0x5),    // Ethernet destination address
        ACTION_SET_NW_SRC((short) 0x6),    // IP source address
        ACTION_SET_NW_DST((short) 0x7),    // IP destination address
        ACTION_SET_NW_TOS((short) 0x8),    // IP ToS (DSCP field, 6 bits)
        ACTION_SET_TP_SRC((short) 0x9),    // TCP/UDP source port
        ACTION_SET_TP_DST((short) 0xa),    // TCP/UDP destination port
        ACTION_ENQUEUE((short) 0xb),    // Output to queue on port
        ACTION_VENDOR((short) 0xffff); // Vendor-specific

        private final short value;    // The value

        /**
         * Constructor for a given value.
         *
         * @param value the value to use for the initialization.
         */
        private ActionValues(short value) {
            this.value = value;
        }

        /**
         * Get the value.
         *
         * @return the value.
         */
        public short getValue() {
            return value;
        }
    }

    /**
     * Action structure for ACTION_OUTPUT: Output to switch port.
     */
    public static class ActionOutput {
        private Port port;    // Output port
        private short maxLen;    // Max. length (in bytes) to send to controller
        // if the port is set to PORT_CONTROLLER

        /**
         * Default constructor.
         */
        public ActionOutput() {
            this.port = null;
            this.maxLen = 0;
        }

        /**
         * Copy constructor.
         *
         * @param other the object to copy from.
         */
        public ActionOutput(ActionOutput other) {
            if (other.port != null)
                this.port = new Port(other.port);
            this.maxLen = other.maxLen;
        }

        /**
         * Constructor from a string.
         * <p/>
         * The string has the following form:
         * [port=XXX maxLen=XXX]
         *
         * @param actionStr the action as a string.
         */
        public ActionOutput(String actionStr) {
            this.fromString(actionStr);
        }

        /**
         * Constructor for a given output port and maximum length.
         *
         * @param port   the output port to set.
         * @param maxLen the maximum length (in bytes) to send to controller
         *               if the port is set to PORT_CONTROLLER.
         */
        public ActionOutput(Port port, short maxLen) {
            this.port = port;
            this.maxLen = maxLen;
        }

        /**
         * Constructor for a given output port.
         *
         * @param port the output port to set.
         */
        public ActionOutput(Port port) {
            this.port = port;
            this.maxLen = 0;
        }

        /**
         * Get the output port.
         *
         * @return the output port.
         */
        @JsonProperty("port")
        public Port port() {
            return this.port;
        }

        /**
         * Get the maximum length (in bytes) to send to controller if the
         * port is set to PORT_CONTROLLER.
         *
         * @return the maximum length (in bytes) to send to controller if the
         * port is set to PORT_CONTROLLER.
         */
        @JsonProperty("maxLen")
        public short maxLen() {
            return this.maxLen;
        }

        /**
         * Convert the action to a string.
         * <p/>
         * The string has the following form:
         * [port=XXX maxLen=XXX]
         *
         * @return the action as a string.
         */
        @Override
        public String toString() {
            String ret = "[";
            ret += "port=" + port.toString();
            ret += " maxLen=" + maxLen;
            ret += "]";

            return ret;
        }

        /**
         * Convert a string to an action.
         * <p/>
         * The string has the following form:
         * [port=XXX maxLen=XXX]
         *
         * @param actionStr the action as a string.
         */
        public void fromString(String actionStr) {
            String[] parts = actionStr.split(" ");
            String decode = null;

            // Decode the "port=XXX" part
            if (parts.length > 0)
                decode = parts[0];
            if (decode != null) {
                String[] tokens = decode.split("port=");
                if (tokens.length > 1 && tokens[1] != null) {
                    try {
                        Short valueShort = Short.valueOf(tokens[1]);
                        port = new Port(valueShort);
                    } catch (NumberFormatException e) {
                        throw new IllegalArgumentException("Invalid action string");
                    }
                }
            } else {
                throw new IllegalArgumentException("Invalid action string");
            }

            // Decode the "maxLen=XXX" part
            decode = null;
            if (parts.length > 1)
                decode = parts[1];
            if (decode != null) {
                decode = decode.replace("]", "");
                String[] tokens = decode.split("maxLen=");
                if (tokens.length > 1 && tokens[1] != null) {
                    try {
                        maxLen = Short.valueOf(tokens[1]);
                    } catch (NumberFormatException e) {
                        throw new IllegalArgumentException("Invalid action string");
                    }
                }
            } else {
                throw new IllegalArgumentException("Invalid action string");
            }
        }
    }

    /**
     * Action structure for ACTION_SET_VLAN_VID: Set the 802.1q VLAN id
     */
    public static class ActionSetVlanId {
        private short vlanId;        // The VLAN ID to set

        /**
         * Default constructor.
         */
        public ActionSetVlanId() {
            this.vlanId = 0;
        }

        /**
         * Copy constructor.
         *
         * @param other the object to copy from.
         */
        public ActionSetVlanId(ActionSetVlanId other) {
            this.vlanId = other.vlanId;
        }

        /**
         * Constructor from a string.
         * <p/>
         * The string has the following form:
         * [vlanId=XXX]
         *
         * @param actionStr the action as a string.
         */
        public ActionSetVlanId(String actionStr) {
            this.fromString(actionStr);
        }

        /**
         * Constructor for a given VLAN ID.
         *
         * @param vlanId the VLAN ID to set.
         */
        public ActionSetVlanId(short vlanId) {
            this.vlanId = vlanId;
        }

        /**
         * Get the VLAN ID.
         *
         * @return the VLAN ID.
         */
        @JsonProperty("vlanId")
        public short vlanId() {
            return this.vlanId;
        }

        /**
         * Convert the action to a string.
         * <p/>
         * The string has the following form:
         * [vlanId=XXX]
         *
         * @return the action as a string.
         */
        @Override
        public String toString() {
            String ret = "[";
            ret += "vlanId=" + this.vlanId;
            ret += "]";

            return ret;
        }

        /**
         * Convert a string to an action.
         * <p/>
         * The string has the following form:
         * [vlanId=XXX]
         *
         * @param actionStr the action as a string.
         */
        public void fromString(String actionStr) {
            String[] parts = actionStr.split("vlanId=");
            String decode = null;

            // Decode the value
            if (parts.length > 1)
                decode = parts[1];
            if (decode != null) {
                decode = decode.replace("]", "");
                try {
                    vlanId = Short.valueOf(decode);
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("Invalid action string");
                }
            } else {
                throw new IllegalArgumentException("Invalid action string");
            }
        }
    }

    /**
     * Action structure for ACTION_SET_VLAN_PCP: Set the 802.1q priority
     */
    public static class ActionSetVlanPriority {
        private byte vlanPriority;    // The VLAN priority to set

        /**
         * Default constructor.
         */
        public ActionSetVlanPriority() {
            this.vlanPriority = 0;
        }

        /**
         * Copy constructor.
         *
         * @param other the object to copy from.
         */
        public ActionSetVlanPriority(ActionSetVlanPriority other) {
            this.vlanPriority = other.vlanPriority;
        }

        /**
         * Constructor from a string.
         * <p/>
         * The string has the following form:
         * [vlanPriority=XXX]
         *
         * @param actionStr the action as a string.
         */
        public ActionSetVlanPriority(String actionStr) {
            this.fromString(actionStr);
        }

        /**
         * Constructor for a given VLAN priority.
         *
         * @param vlanPriority the VLAN priority to set.
         */
        public ActionSetVlanPriority(byte vlanPriority) {
            this.vlanPriority = vlanPriority;
        }

        /**
         * Get the VLAN priority.
         *
         * @return the VLAN priority.
         */
        @JsonProperty("vlanPriority")
        public byte vlanPriority() {
            return this.vlanPriority;
        }

        /**
         * Convert the action to a string.
         * <p/>
         * The string has the following form:
         * [vlanPriority=XXX]
         *
         * @return the action as a string.
         */
        @Override
        public String toString() {
            String ret = "[";
            ret += "vlanPriority=" + this.vlanPriority;
            ret += "]";

            return ret;
        }

        /**
         * Convert a string to an action.
         * <p/>
         * The string has the following form:
         * [vlanPriority=XXX]
         *
         * @param actionStr the action as a string.
         */
        public void fromString(String actionStr) {
            String[] parts = actionStr.split("vlanPriority=");
            String decode = null;

            // Decode the value
            if (parts.length > 1)
                decode = parts[1];
            if (decode != null) {
                decode = decode.replace("]", "");
                try {
                    vlanPriority = Byte.valueOf(decode);
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("Invalid action string");
                }
            } else {
                throw new IllegalArgumentException("Invalid action string");
            }
        }
    }

    /**
     * Action structure for ACTION_STRIP_VLAN: Strip the 802.1q header
     */
    public static class ActionStripVlan {
        private boolean stripVlan;    // If true, strip the VLAN header

        /**
         * Default constructor.
         */
        public ActionStripVlan() {
            this.stripVlan = false;
        }

        /**
         * Copy constructor.
         *
         * @param other the object to copy from.
         */
        public ActionStripVlan(ActionStripVlan other) {
            this.stripVlan = other.stripVlan;
        }

        /**
         * Constructor from a string.
         * <p/>
         * The string has the following form:
         * [stripVlan=XXX]
         *
         * @param actionStr the action as a string.
         */
        public ActionStripVlan(String actionStr) {
            this.fromString(actionStr);
        }

        /**
         * Constructor for a given boolean flag.
         *
         * @param stripVlan if true, strip the VLAN header.
         */
        public ActionStripVlan(boolean stripVlan) {
            this.stripVlan = stripVlan;
        }

        /**
         * Get the boolean flag whether the VLAN header should be stripped.
         *
         * @return the boolean flag whether the VLAN header should be stripped.
         */
        @JsonProperty("stripVlan")
        public boolean stripVlan() {
            return this.stripVlan;
        }

        /**
         * Convert the action to a string.
         * <p/>
         * The string has the following form:
         * [stripVlan=XXX]
         *
         * @return the action as a string.
         */
        @Override
        public String toString() {
            String ret = "[";
            ret += "stripVlan=" + this.stripVlan;
            ret += "]";

            return ret;
        }

        /**
         * Convert a string to an action.
         * <p/>
         * The string has the following form:
         * [stripVlan=XXX]
         *
         * @param actionStr the action as a string.
         */
        public void fromString(String actionStr) {
            String[] parts = actionStr.split("stripVlan=");
            String decode = null;

            // Decode the value
            if (parts.length > 1)
                decode = parts[1];
            if (decode != null) {
                decode = decode.replace("]", "");
                stripVlan = Boolean.valueOf(decode);
            } else {
                throw new IllegalArgumentException("Invalid action string");
            }
        }
    }

    /**
     * Action structure for ACTION_SET_DL_SRC and ACTION_SET_DL_DST:
     * Set the Ethernet source/destination address.
     */
    public static class ActionSetEthernetAddr {
        private MACAddress addr;    // The MAC address to set

        /**
         * Default constructor.
         */
        public ActionSetEthernetAddr() {
            this.addr = null;
        }

        /**
         * Copy constructor.
         *
         * @param other the object to copy from.
         */
        public ActionSetEthernetAddr(ActionSetEthernetAddr other) {
            if (other.addr != null)
                this.addr = MACAddress.valueOf(other.addr.toLong());
        }

        /**
         * Constructor from a string.
         * <p/>
         * The string has the following form:
         * [addr=XXX]
         *
         * @param actionStr the action as a string.
         */
        public ActionSetEthernetAddr(String actionStr) {
            this.fromString(actionStr);
        }

        /**
         * Constructor for a given MAC address.
         *
         * @param addr the MAC address to set.
         */
        public ActionSetEthernetAddr(MACAddress addr) {
            this.addr = addr;
        }

        /**
         * Get the MAC address.
         *
         * @return the MAC address.
         */
        @JsonProperty("addr")
        public MACAddress addr() {
            return this.addr;
        }

        /**
         * Convert the action to a string.
         * <p/>
         * The string has the following form:
         * [addr=XXX]
         *
         * @return the action as a string.
         */
        @Override
        public String toString() {
            String ret = "[";
            ret += "addr=" + addr.toString();
            ret += "]";

            return ret;
        }

        /**
         * Convert a string to an action.
         * <p/>
         * The string has the following form:
         * [addr=XXX]
         *
         * @param actionStr the action as a string.
         */
        public void fromString(String actionStr) {
            String[] parts = actionStr.split("addr=");
            String decode = null;

            // Decode the value
            if (parts.length > 1)
                decode = parts[1];
            if (decode != null) {
                decode = decode.replace("]", "");
                try {
                    addr = MACAddress.valueOf(decode);
                } catch (IllegalArgumentException e) {
                    throw new IllegalArgumentException("Invalid action string");
                }
            } else {
                throw new IllegalArgumentException("Invalid action string");
            }
        }
    }

    /**
     * Action structure for ACTION_SET_NW_SRC and ACTION_SET_NW_DST:
     * Set the IPv4 source/destination address.
     */
    public static class ActionSetIPv4Addr {
        private IPv4 addr;        // The IPv4 address to set

        /**
         * Default constructor.
         */
        public ActionSetIPv4Addr() {
            this.addr = null;
        }

        /**
         * Copy constructor.
         *
         * @param other the object to copy from.
         */
        public ActionSetIPv4Addr(ActionSetIPv4Addr other) {
            if (other.addr != null)
                this.addr = new IPv4(other.addr);
        }

        /**
         * Constructor from a string.
         * <p/>
         * The string has the following form:
         * [addr=XXX]
         *
         * @param actionStr the action as a string.
         */
        public ActionSetIPv4Addr(String actionStr) {
            this.fromString(actionStr);
        }

        /**
         * Constructor for a given IPv4 address.
         *
         * @param addr the IPv4 address to set.
         */
        public ActionSetIPv4Addr(IPv4 addr) {
            this.addr = addr;
        }

        /**
         * Get the IPv4 address.
         *
         * @return the IPv4 address.
         */
        @JsonProperty("addr")
        public IPv4 addr() {
            return this.addr;
        }

        /**
         * Convert the action to a string.
         * <p/>
         * The string has the following form:
         * [addr=XXX]
         *
         * @return the action as a string.
         */
        @Override
        public String toString() {
            String ret = "[";
            ret += "addr=" + addr.toString();
            ret += "]";

            return ret;
        }

        /**
         * Convert a string to an action.
         * <p/>
         * The string has the following form:
         * [addr=XXX]
         *
         * @param actionStr the action as a string.
         */
        public void fromString(String actionStr) {
            String[] parts = actionStr.split("addr=");
            String decode = null;

            // Decode the value
            if (parts.length > 1)
                decode = parts[1];
            if (decode != null) {
                decode = decode.replace("]", "");
                try {
                    addr = new IPv4(decode);
                } catch (IllegalArgumentException e) {
                    throw new IllegalArgumentException("Invalid action string");
                }
            } else {
                throw new IllegalArgumentException("Invalid action string");
            }
        }
    }

    /**
     * Action structure for ACTION_SET_NW_TOS:
     * Set the IP ToS (DSCP field, 6 bits).
     */
    public static class ActionSetIpToS {
        private byte ipToS;    // The IP ToS to set DSCP field, 6 bits)

        /**
         * Default constructor.
         */
        public ActionSetIpToS() {
            this.ipToS = 0;
        }

        /**
         * Copy constructor.
         *
         * @param other the object to copy from.
         */
        public ActionSetIpToS(ActionSetIpToS other) {
            this.ipToS = other.ipToS;
        }

        /**
         * Constructor from a string.
         * <p/>
         * The string has the following form:
         * [ipToS=XXX]
         *
         * @param actionStr the action as a string.
         */
        public ActionSetIpToS(String actionStr) {
            this.fromString(actionStr);
        }

        /**
         * Constructor for a given IP ToS (DSCP field, 6 bits).
         *
         * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
         */
        public ActionSetIpToS(byte ipToS) {
            this.ipToS = ipToS;
        }

        /**
         * Get the IP ToS (DSCP field, 6 bits).
         *
         * @return the IP ToS (DSCP field, 6 bits).
         */
        @JsonProperty("ipToS")
        public byte ipToS() {
            return this.ipToS;
        }

        /**
         * Convert the action to a string.
         * <p/>
         * The string has the following form:
         * [ipToS=XXX]
         *
         * @return the action as a string.
         */
        @Override
        public String toString() {
            String ret = "[";
            ret += "ipToS=" + ipToS;
            ret += "]";

            return ret;
        }

        /**
         * Convert a string to an action.
         * <p/>
         * The string has the following form:
         * [ipToS=XXX]
         *
         * @param actionStr the action as a string.
         */
        public void fromString(String actionStr) {
            String[] parts = actionStr.split("ipToS=");
            String decode = null;

            // Decode the value
            if (parts.length > 1)
                decode = parts[1];
            if (decode != null) {
                decode = decode.replace("]", "");
                try {
                    ipToS = Byte.valueOf(decode);
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("Invalid action string");
                }
            } else {
                throw new IllegalArgumentException("Invalid action string");
            }
        }
    }

    /**
     * Action structure for ACTION_SET_TP_SRC and ACTION_SET_TP_DST:
     * Set the TCP/UDP source/destination port.
     */
    public static class ActionSetTcpUdpPort {
        private short port;        // The TCP/UDP port to set

        /**
         * Default constructor.
         */
        public ActionSetTcpUdpPort() {
            this.port = 0;
        }

        /**
         * Copy constructor.
         *
         * @param other the object to copy from.
         */
        public ActionSetTcpUdpPort(ActionSetTcpUdpPort other) {
            this.port = other.port;
        }

        /**
         * Constructor from a string.
         * <p/>
         * The string has the following form:
         * [port=XXX]
         *
         * @param actionStr the action as a string.
         */
        public ActionSetTcpUdpPort(String actionStr) {
            this.fromString(actionStr);
        }

        /**
         * Constructor for a given TCP/UDP port.
         *
         * @param port the TCP/UDP port to set.
         */
        public ActionSetTcpUdpPort(short port) {
            this.port = port;
        }

        /**
         * Get the TCP/UDP port.
         *
         * @return the TCP/UDP port.
         */
        @JsonProperty("port")
        public short port() {
            return this.port;
        }

        /**
         * Convert the action to a string.
         * <p/>
         * The string has the following form:
         * [port=XXX]
         *
         * @return the action as a string.
         */
        @Override
        public String toString() {
            String ret = "[";
            ret += "port=" + port;
            ret += "]";

            return ret;
        }

        /**
         * Convert a string to an action.
         * <p/>
         * The string has the following form:
         * [port=XXX]
         *
         * @param actionStr the action as a string.
         */
        public void fromString(String actionStr) {
            String[] parts = actionStr.split("port=");
            String decode = null;

            // Decode the value
            if (parts.length > 1)
                decode = parts[1];
            if (decode != null) {
                decode = decode.replace("]", "");
                try {
                    port = Short.valueOf(decode);
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("Invalid action string");
                }
            } else {
                throw new IllegalArgumentException("Invalid action string");
            }
        }
    }

    /**
     * Action structure for ACTION_ENQUEUE: Output to queue on port.
     */
    public static class ActionEnqueue {
        private Port port;    // Port that queue belongs. Should
        // refer to a valid physical port
        // (i.e. < PORT_MAX) or PORT_IN_PORT
        private int queueId;    // Where to enqueue the packets

        /**
         * Default constructor.
         */
        public ActionEnqueue() {
            this.port = null;
            this.queueId = 0;
        }

        /**
         * Copy constructor.
         *
         * @param other the object to copy from.
         */
        public ActionEnqueue(ActionEnqueue other) {
            if (other.port != null)
                this.port = new Port(other.port);
            this.queueId = other.queueId;
        }

        /**
         * Constructor from a string.
         * <p/>
         * The string has the following form:
         * [port=XXX queueId=XXX]
         *
         * @param actionStr the action as a string.
         */
        public ActionEnqueue(String actionStr) {
            this.fromString(actionStr);
        }

        /**
         * Constructor for a given port and queue ID.
         *
         * @param port    the port to set.
         * @param queueId the queue ID on the port.
         */
        public ActionEnqueue(Port port, int queueId) {
            this.port = port;
            this.queueId = queueId;
        }

        /**
         * Get the port.
         *
         * @return the port.
         */
        @JsonProperty("port")
        public Port port() {
            return this.port;
        }

        /**
         * Get the queue ID.
         *
         * @return the queue ID.
         */
        @JsonProperty("queueId")
        public int queueId() {
            return this.queueId;
        }

        /**
         * Convert the action to a string.
         * <p/>
         * The string has the following form:
         * [port=XXX queueId=XXX]
         *
         * @return the action as a string.
         */
        @Override
        public String toString() {
            String ret = "[";
            ret += "port=" + port.toString();
            ret += " queueId=" + queueId;
            ret += "]";

            return ret;
        }

        /**
         * Convert a string to an action.
         * <p/>
         * The string has the following form:
         * [port=XXX queueId=XXX]
         *
         * @param actionStr the action as a string.
         */
        public void fromString(String actionStr) {
            String[] parts = actionStr.split(" ");
            String decode = null;

            // Decode the "port=XXX" part
            if (parts.length > 0)
                decode = parts[0];
            if (decode != null) {
                String[] tokens = decode.split("port=");
                if (tokens.length > 1 && tokens[1] != null) {
                    try {
                        Short valueShort = Short.valueOf(tokens[1]);
                        port = new Port(valueShort);
                    } catch (NumberFormatException e) {
                        throw new IllegalArgumentException("Invalid action string");
                    }
                }
            } else {
                throw new IllegalArgumentException("Invalid action string");
            }

            // Decode the "queueId=XXX" part
            decode = null;
            if (parts.length > 1)
                decode = parts[1];
            if (decode != null) {
                decode = decode.replace("]", "");
                String[] tokens = decode.split("queueId=");
                if (tokens.length > 1 && tokens[1] != null) {
                    try {
                        queueId = Short.valueOf(tokens[1]);
                    } catch (NumberFormatException e) {
                        throw new IllegalArgumentException("Invalid action string");
                    }
                }
            } else {
                throw new IllegalArgumentException("Invalid action string");
            }
        }
    }

    private ActionValues actionType;    // The action type

    //
    // The actions.
    // NOTE: Only one action should be set.
    //
    private ActionOutput actionOutput;
    private ActionSetVlanId actionSetVlanId;
    private ActionSetVlanPriority actionSetVlanPriority;
    private ActionStripVlan actionStripVlan;
    private ActionSetEthernetAddr actionSetEthernetSrcAddr;
    private ActionSetEthernetAddr actionSetEthernetDstAddr;
    private ActionSetIPv4Addr actionSetIPv4SrcAddr;
    private ActionSetIPv4Addr actionSetIPv4DstAddr;
    private ActionSetIpToS actionSetIpToS;
    private ActionSetTcpUdpPort actionSetTcpUdpSrcPort;
    private ActionSetTcpUdpPort actionSetTcpUdpDstPort;
    private ActionEnqueue actionEnqueue;

    /**
     * Default constructor.
     */
    public FlowEntryAction() {
        actionType = ActionValues.ACTION_VENDOR;    // XXX: Initial value
    }

    /**
     * Copy constructor.
     *
     * @param other the object to copy from.
     */
    public FlowEntryAction(FlowEntryAction other) {
        this.actionType = other.actionType;

        //
        if (other.actionOutput != null)
            this.actionOutput = new ActionOutput(other.actionOutput);
        else
            this.actionOutput = null;
        //
        if (other.actionSetVlanId != null)
            this.actionSetVlanId = new ActionSetVlanId(other.actionSetVlanId);
        else
            this.actionSetVlanId = null;
        //
        if (other.actionSetVlanPriority != null)
            this.actionSetVlanPriority = new ActionSetVlanPriority(other.actionSetVlanPriority);
        else
            this.actionSetVlanPriority = null;
        //
        if (other.actionStripVlan != null)
            this.actionStripVlan = new ActionStripVlan(other.actionStripVlan);
        else
            this.actionStripVlan = null;
        //
        if (other.actionSetEthernetSrcAddr != null)
            this.actionSetEthernetSrcAddr = new ActionSetEthernetAddr(other.actionSetEthernetSrcAddr);
        else
            this.actionSetEthernetSrcAddr = null;
        //
        if (other.actionSetEthernetDstAddr != null)
            this.actionSetEthernetDstAddr = new ActionSetEthernetAddr(other.actionSetEthernetDstAddr);
        else
            this.actionSetEthernetDstAddr = null;
        //
        if (other.actionSetIPv4SrcAddr != null)
            this.actionSetIPv4SrcAddr = new ActionSetIPv4Addr(other.actionSetIPv4SrcAddr);
        else
            this.actionSetIPv4SrcAddr = null;
        //
        if (other.actionSetIPv4DstAddr != null)
            this.actionSetIPv4DstAddr = new ActionSetIPv4Addr(other.actionSetIPv4DstAddr);
        else
            this.actionSetIPv4DstAddr = null;
        //
        if (other.actionSetIpToS != null)
            this.actionSetIpToS = new ActionSetIpToS(other.actionSetIpToS);
        else
            this.actionSetIpToS = null;
        //
        if (other.actionSetTcpUdpSrcPort != null)
            this.actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(other.actionSetTcpUdpSrcPort);
        else
            this.actionSetTcpUdpSrcPort = null;
        //
        if (other.actionSetTcpUdpDstPort != null)
            this.actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(other.actionSetTcpUdpDstPort);
        else
            this.actionSetTcpUdpDstPort = null;
        //
        if (other.actionEnqueue != null)
            this.actionEnqueue = new ActionEnqueue(other.actionEnqueue);
        else
            this.actionEnqueue = null;
    }

    /**
     * Constructor from a string.
     * <p/>
     * The string has the following form:
     * [type=XXX action=XXX]
     *
     * @param actionStr the action as a string.
     */
    public FlowEntryAction(String actionStr) {
        this.fromString(actionStr);
    }

    /**
     * Get the action type.
     *
     * @return the action type.
     */
    @JsonProperty("actionType")
    public ActionValues actionType() {
        return actionType;
    }

    /**
     * Get the output action.
     *
     * @return the output action.
     */
    @JsonProperty("actionOutput")
    public ActionOutput actionOutput() {
        return actionOutput;
    }

    /**
     * Set the output action on a port.
     *
     * @param action the action to set.
     */
    @JsonProperty("actionOutput")
    public void setActionOutput(ActionOutput action) {
        actionOutput = action;
        actionType = ActionValues.ACTION_OUTPUT;
    }

    /**
     * Set the output action on a port.
     *
     * @param port the output port to set.
     */
    public void setActionOutput(Port port) {
        actionOutput = new ActionOutput(port);
        actionType = ActionValues.ACTION_OUTPUT;
    }

    /**
     * Set the output action to controller.
     *
     * @param maxLen the maximum length (in bytes) to send to controller.
     */
    public void setActionOutputToController(short maxLen) {
        Port port = new Port(Port.PortValues.PORT_CONTROLLER);
        actionOutput = new ActionOutput(port, maxLen);
        actionType = ActionValues.ACTION_OUTPUT;
    }

    /**
     * Get the action to set the VLAN ID.
     *
     * @return the action to set the VLAN ID.
     */
    @JsonProperty("actionSetVlanId")
    public ActionSetVlanId actionSetVlanId() {
        return actionSetVlanId;
    }

    /**
     * Set the action to set the VLAN ID.
     *
     * @param action the action to set.
     */
    @JsonProperty("actionSetVlanId")
    public void setActionSetVlanId(ActionSetVlanId action) {
        actionSetVlanId = action;
        actionType = ActionValues.ACTION_SET_VLAN_VID;
    }

    /**
     * Set the action to set the VLAN ID.
     *
     * @param vlanId the VLAN ID to set.
     */
    public void setActionSetVlanId(short vlanId) {
        actionSetVlanId = new ActionSetVlanId(vlanId);
        actionType = ActionValues.ACTION_SET_VLAN_VID;
    }

    /**
     * Get the action to set the VLAN priority.
     *
     * @return the action to set the VLAN priority.
     */
    @JsonProperty("actionSetVlanPriority")
    public ActionSetVlanPriority actionSetVlanPriority() {
        return actionSetVlanPriority;
    }

    /**
     * Set the action to set the VLAN priority.
     *
     * @param action the action to set.
     */
    @JsonProperty("actionSetVlanPriority")
    public void setActionSetVlanPriority(ActionSetVlanPriority action) {
        actionSetVlanPriority = action;
        actionType = ActionValues.ACTION_SET_VLAN_PCP;
    }

    /**
     * Set the action to set the VLAN priority.
     *
     * @param vlanPriority the VLAN priority to set.
     */
    public void setActionSetVlanPriority(byte vlanPriority) {
        actionSetVlanPriority = new ActionSetVlanPriority(vlanPriority);
        actionType = ActionValues.ACTION_SET_VLAN_PCP;
    }

    /**
     * Get the action to strip the VLAN header.
     *
     * @return the action to strip the VLAN header.
     */
    @JsonProperty("actionStripVlan")
    public ActionStripVlan actionStripVlan() {
        return actionStripVlan;
    }

    /**
     * Set the action to strip the VLAN header.
     *
     * @param action the action to set.
     */
    @JsonProperty("actionStripVlan")
    public void setActionStripVlan(ActionStripVlan action) {
        actionStripVlan = action;
        actionType = ActionValues.ACTION_STRIP_VLAN;
    }

    /**
     * Set the action to strip the VLAN header.
     *
     * @param stripVlan if true, strip the VLAN header.
     */
    public void setActionStripVlan(boolean stripVlan) {
        actionStripVlan = new ActionStripVlan(stripVlan);
        actionType = ActionValues.ACTION_STRIP_VLAN;
    }

    /**
     * Get the action to set the Ethernet source address.
     *
     * @return the action to set the Ethernet source address.
     */
    @JsonProperty("actionSetEthernetSrcAddr")
    public ActionSetEthernetAddr actionSetEthernetSrcAddr() {
        return actionSetEthernetSrcAddr;
    }

    /**
     * Set the action to set the Ethernet source address.
     *
     * @param action the action to set.
     */
    @JsonProperty("actionSetEthernetSrcAddr")
    public void setActionSetEthernetSrcAddr(ActionSetEthernetAddr action) {
        actionSetEthernetSrcAddr = action;
        actionType = ActionValues.ACTION_SET_DL_SRC;
    }

    /**
     * Set the action to set the Ethernet source address.
     *
     * @param addr the MAC address to set as the Ethernet source address.
     */
    public void setActionSetEthernetSrcAddr(MACAddress addr) {
        actionSetEthernetSrcAddr = new ActionSetEthernetAddr(addr);
        actionType = ActionValues.ACTION_SET_DL_SRC;
    }

    /**
     * Get the action to set the Ethernet destination address.
     *
     * @return the action to set the Ethernet destination address.
     */
    @JsonProperty("actionSetEthernetDstAddr")
    public ActionSetEthernetAddr actionSetEthernetDstAddr() {
        return actionSetEthernetDstAddr;
    }

    /**
     * Set the action to set the Ethernet destination address.
     *
     * @param action the action to set.
     */
    @JsonProperty("actionSetEthernetDstAddr")
    public void setActionSetEthernetDstAddr(ActionSetEthernetAddr action) {
        actionSetEthernetDstAddr = action;
        actionType = ActionValues.ACTION_SET_DL_DST;
    }

    /**
     * Set the action to set the Ethernet destination address.
     *
     * @param addr the MAC address to set as the Ethernet destination address.
     */
    public void setActionSetEthernetDstAddr(MACAddress addr) {
        actionSetEthernetDstAddr = new ActionSetEthernetAddr(addr);
        actionType = ActionValues.ACTION_SET_DL_DST;
    }

    /**
     * Get the action to set the IPv4 source address.
     *
     * @return the action to set the IPv4 source address.
     */
    @JsonProperty("actionSetIPv4SrcAddr")
    public ActionSetIPv4Addr actionSetIPv4SrcAddr() {
        return actionSetIPv4SrcAddr;
    }

    /**
     * Set the action to set the IPv4 source address.
     *
     * @param action the action to set.
     */
    @JsonProperty("actionSetIPv4SrcAddr")
    public void setActionSetIPv4SrcAddr(ActionSetIPv4Addr action) {
        actionSetIPv4SrcAddr = action;
        actionType = ActionValues.ACTION_SET_NW_SRC;
    }

    /**
     * Set the action to set the IPv4 source address.
     *
     * @param addr the IPv4 address to set as the IPv4 source address.
     */
    public void setActionSetIPv4SrcAddr(IPv4 addr) {
        actionSetIPv4SrcAddr = new ActionSetIPv4Addr(addr);
        actionType = ActionValues.ACTION_SET_NW_SRC;
    }

    /**
     * Get the action to set the IPv4 destination address.
     *
     * @return the action to set the IPv4 destination address.
     */
    @JsonProperty("actionSetIPv4DstAddr")
    public ActionSetIPv4Addr actionSetIPv4DstAddr() {
        return actionSetIPv4DstAddr;
    }

    /**
     * Set the action to set the IPv4 destination address.
     *
     * @param action the action to set.
     */
    @JsonProperty("actionSetIPv4DstAddr")
    public void setActionSetIPv4DstAddr(ActionSetIPv4Addr action) {
        actionSetIPv4DstAddr = action;
        actionType = ActionValues.ACTION_SET_NW_DST;
    }

    /**
     * Set the action to set the IPv4 destination address.
     *
     * @param addr the IPv4 address to set as the IPv4 destination address.
     */
    public void setActionSetIPv4DstAddr(IPv4 addr) {
        actionSetIPv4DstAddr = new ActionSetIPv4Addr(addr);
        actionType = ActionValues.ACTION_SET_NW_DST;
    }

    /**
     * Get the action to set the IP ToS (DSCP field, 6 bits).
     *
     * @return the action to set the IP ToS (DSCP field, 6 bits).
     */
    @JsonProperty("actionSetIpToS")
    public ActionSetIpToS actionSetIpToS() {
        return actionSetIpToS;
    }

    /**
     * Set the action to set the IP ToS (DSCP field, 6 bits).
     *
     * @param action the action to set.
     */
    @JsonProperty("actionSetIpToS")
    public void setActionSetIpToS(ActionSetIpToS action) {
        actionSetIpToS = action;
        actionType = ActionValues.ACTION_SET_NW_TOS;
    }

    /**
     * Set the action to set the IP ToS (DSCP field, 6 bits).
     *
     * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
     */
    public void setActionSetIpToS(byte ipToS) {
        actionSetIpToS = new ActionSetIpToS(ipToS);
        actionType = ActionValues.ACTION_SET_NW_TOS;
    }

    /**
     * Get the action to set the TCP/UDP source port.
     *
     * @return the action to set the TCP/UDP source port.
     */
    @JsonProperty("actionSetTcpUdpSrcPort")
    public ActionSetTcpUdpPort actionSetTcpUdpSrcPort() {
        return actionSetTcpUdpSrcPort;
    }

    /**
     * Set the action to set the TCP/UDP source port.
     *
     * @param action the action to set.
     */
    @JsonProperty("actionSetTcpUdpSrcPort")
    public void setActionSetTcpUdpSrcPort(ActionSetTcpUdpPort action) {
        actionSetTcpUdpSrcPort = action;
        actionType = ActionValues.ACTION_SET_TP_SRC;
    }

    /**
     * Set the action to set the TCP/UDP source port.
     *
     * @param port the TCP/UDP port to set as the TCP/UDP source port.
     */
    public void setActionSetTcpUdpSrcPort(short port) {
        actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(port);
        actionType = ActionValues.ACTION_SET_TP_SRC;
    }

    /**
     * Get the action to set the TCP/UDP destination port.
     *
     * @return the action to set the TCP/UDP destination port.
     */
    @JsonProperty("actionSetTcpUdpDstPort")
    public ActionSetTcpUdpPort actionSetTcpUdpDstPort() {
        return actionSetTcpUdpDstPort;
    }

    /**
     * Set the action to set the TCP/UDP destination port.
     *
     * @param action the action to set.
     */
    @JsonProperty("actionSetTcpUdpDstPort")
    public void setActionSetTcpUdpDstPort(ActionSetTcpUdpPort action) {
        actionSetTcpUdpDstPort = action;
        actionType = ActionValues.ACTION_SET_TP_DST;
    }

    /**
     * Set the action to set the TCP/UDP destination port.
     *
     * @param port the TCP/UDP port to set as the TCP/UDP destination port.
     */
    public void setActionSetTcpUdpDstPort(short port) {
        actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(port);
        actionType = ActionValues.ACTION_SET_TP_DST;
    }

    /**
     * Get the action to output to queue on a port.
     *
     * @return the action to output to queue on a port.
     */
    @JsonProperty("actionEnqueue")
    public ActionEnqueue actionEnqueue() {
        return actionEnqueue;
    }

    /**
     * Set the action to output to queue on a port.
     *
     * @param action the action to set.
     */
    @JsonProperty("actionEnqueue")
    public void setActionEnqueue(ActionEnqueue action) {
        actionEnqueue = action;
        actionType = ActionValues.ACTION_ENQUEUE;
    }

    /**
     * Set the action to output to queue on a port.
     *
     * @param port    the port to set.
     * @param queueId the queue ID to set.
     */
    public void setActionEnqueue(Port port, int queueId) {
        actionEnqueue = new ActionEnqueue(port, queueId);
        actionType = ActionValues.ACTION_ENQUEUE;
    }

    /**
     * Convert the action to a string.
     * <p/>
     * The string has the following form:
     * [type=XXX action=XXX]
     *
     * @return the action as a string.
     */
    @Override
    public String toString() {
        String ret = "[";
        ret += "type=" + actionType;
        switch (actionType) {
            case ACTION_OUTPUT:
                ret += " action=" + actionOutput.toString();
                break;
            case ACTION_SET_VLAN_VID:
                ret += " action=" + actionSetVlanId.toString();
                break;
            case ACTION_SET_VLAN_PCP:
                ret += " action=" + actionSetVlanPriority.toString();
                break;
            case ACTION_STRIP_VLAN:
                ret += " action=" + actionStripVlan.toString();
                break;
            case ACTION_SET_DL_SRC:
                ret += " action=" + actionSetEthernetSrcAddr.toString();
                break;
            case ACTION_SET_DL_DST:
                ret += " action=" + actionSetEthernetDstAddr.toString();
                break;
            case ACTION_SET_NW_SRC:
                ret += " action=" + actionSetIPv4SrcAddr.toString();
                break;
            case ACTION_SET_NW_DST:
                ret += " action=" + actionSetIPv4DstAddr.toString();
                break;
            case ACTION_SET_NW_TOS:
                ret += " action=" + actionSetIpToS.toString();
                break;
            case ACTION_SET_TP_SRC:
                ret += " action=" + actionSetTcpUdpSrcPort.toString();
                break;
            case ACTION_SET_TP_DST:
                ret += " action=" + actionSetTcpUdpDstPort.toString();
                break;
            case ACTION_ENQUEUE:
                ret += " action=" + actionEnqueue.toString();
                break;
            case ACTION_VENDOR:
                ret += " action=VENDOR";
                break;
        }
        ret += "]";

        return ret;
    }

    /**
     * Convert a string to an action.
     * <p/>
     * The string has the following form:
     * [type=XXX action=XXX]
     *
     * @param actionStr the action as a string.
     */
    public void fromString(String actionStr) {
        String[] parts = actionStr.split("type=");
        String decode = null;

        // Extract the string after the "type="
        if (parts.length > 1)
            decode = parts[1];
        if (decode == null)
            throw new IllegalArgumentException("Invalid action string");

        // Remove the trailing ']'
        if ((decode.length() > 0) && (decode.charAt(decode.length() - 1) == ']')) {
            decode = decode.substring(0, decode.length() - 1);
        } else {
            throw new IllegalArgumentException("Invalid action string");
        }

        // Extract the type value and the action value
        parts = decode.split(" action=");

        // Decode the "type=XXX" payload
        if (parts.length > 0)
            decode = parts[0];
        if (decode != null) {
            try {
                actionType = Enum.valueOf(ActionValues.class, decode);
            } catch (IllegalArgumentException e) {
                throw new IllegalArgumentException("Invalid action string");
            }
        } else {
            throw new IllegalArgumentException("Invalid action string");
        }

        // Decode the "action=XXX" payload
        decode = null;
        if (parts.length > 1)
            decode = parts[1];
        if (decode == null)
            throw new IllegalArgumentException("Invalid action string");
        //
        try {
            switch (actionType) {
                case ACTION_OUTPUT:
                    actionOutput = new ActionOutput(decode);
                    break;
                case ACTION_SET_VLAN_VID:
                    actionSetVlanId = new ActionSetVlanId(decode);
                    break;
                case ACTION_SET_VLAN_PCP:
                    actionSetVlanPriority = new ActionSetVlanPriority(decode);
                    break;
                case ACTION_STRIP_VLAN:
                    actionStripVlan = new ActionStripVlan(decode);
                    break;
                case ACTION_SET_DL_SRC:
                    actionSetEthernetSrcAddr = new ActionSetEthernetAddr(decode);
                    break;
                case ACTION_SET_DL_DST:
                    actionSetEthernetDstAddr = new ActionSetEthernetAddr(decode);
                    break;
                case ACTION_SET_NW_SRC:
                    actionSetIPv4SrcAddr = new ActionSetIPv4Addr(decode);
                    break;
                case ACTION_SET_NW_DST:
                    actionSetIPv4DstAddr = new ActionSetIPv4Addr(decode);
                    break;
                case ACTION_SET_NW_TOS:
                    actionSetIpToS = new ActionSetIpToS(decode);
                    break;
                case ACTION_SET_TP_SRC:
                    actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(decode);
                    break;
                case ACTION_SET_TP_DST:
                    actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(decode);
                    break;
                case ACTION_ENQUEUE:
                    actionEnqueue = new ActionEnqueue(decode);
                    break;
                case ACTION_VENDOR:
                    // TODO: Handle it as appropriate
                    break;
            }
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("Invalid action string");
        }
    }
}
