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 {
                        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.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);
        }
    }
}
