package net.onrc.onos.ofcontroller.util;

import net.floodlightcontroller.util.MACAddress;

import org.codehaus.jackson.annotate.JsonProperty;

/**
 * The class representing a single Flow Entry action.
 *
 * 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.
     *
     * 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;
	}
    }

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

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

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

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

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

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

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

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

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

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

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

    /**
     * Action structure for ACTION_SET_VLAN_VID: Set the 802.1q VLAN id
     */
    public 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.
	 *
	 * 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.
	 *
	 * 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.
	 *
	 * 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 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.
	 *
	 * 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.
	 *
	 * 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.
	 *
	 * 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 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.
	 *
	 * 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.
	 *
	 * 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.
	 *
	 * 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 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.
	 *
	 * 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.
	 *
	 * 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.
	 *
	 * 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 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.
	 *
	 * 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.
	 *
	 * 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.
	 *
	 * 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 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.
	 *
	 * 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.
	 *
	 * 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.
	 *
	 * 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 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.
	 *
	 * 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.
	 *
	 * 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.
	 *
	 * 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 class ActionEnqueue {
	private Port port;	// Port that queue belongs. Should
				// refer to a valid physical port
				// (i.e. < PORT_MAX) or PORT_IN_PORT
	private int queueId;	// Where to enqueue the packets

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

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

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

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

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

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

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

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

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

    private ActionValues actionType;	// The action type

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * Convert the action to a string.
     *
     * 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;
	}
	ret += "]";

	return ret;
    }

    /**
     * Convert a string to an action.
     *
     * 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;
	    }
	} catch (IllegalArgumentException e) {
	    throw new IllegalArgumentException("Invalid action string");
	}
    }
}
