package net.onrc.onos.core.util;

import net.floodlightcontroller.util.MACAddress;

import org.codehaus.jackson.annotate.JsonProperty;
import org.projectfloodlight.openflow.types.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 {
                        port = new PortNumber(tokens[1]);
                    } 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.CONTROLLER.getShortPortNumber());
        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);
        }
    }
}
