package net.onrc.onos.core.util;

import net.floodlightcontroller.util.MACAddress;

import org.codehaus.jackson.annotate.JsonProperty;
import org.openflow.protocol.OFPort;

/**
 * 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 PortNumber 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 PortNumber(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(PortNumber port, short maxLen) {
            this.port = port;
            this.maxLen = maxLen;
        }

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

        /**
         * Get the output port.
         *
         * @return the output port.
         */
        @JsonProperty("port")
        public PortNumber 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 PortNumber(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 PortNumber 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 PortNumber(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(PortNumber port, int queueId) {
            this.port = port;
            this.queueId = queueId;
        }

        /**
         * Get the port.
         *
         * @return the port.
         */
        @JsonProperty("port")
        public PortNumber 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 PortNumber(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(PortNumber 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) {
        PortNumber port = new PortNumber(OFPort.OFPP_CONTROLLER.getValue());
        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(PortNumber 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;
            default:
                ret += " action=unknown";
                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;
                default:
                    throw new IllegalArgumentException("Invalid action string");
            }
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("Invalid action type", e);
        }
    }
}
