package net.onrc.onos.core.util;

import net.floodlightcontroller.util.MACAddress;

import org.codehaus.jackson.annotate.JsonProperty;

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

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

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

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

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

	/**
	 * Constructor from a string.
	 *
	 * 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 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.
	 *
	 * 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 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.
	 *
	 * 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 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.
	 *
	 * 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 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.
	 *
	 * 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 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.
	 *
	 * 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 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.
	 *
	 * 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 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.
	 *
	 * 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 static class ActionEnqueue {
	private Port port;	// Port that queue belongs. Should
				// refer to a valid physical port
				// (i.e. < PORT_MAX) or PORT_IN_PORT
	private int queueId;	// Where to enqueue the packets

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

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

	/**
	 * Constructor from a string.
	 *
	 * 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;
	case ACTION_VENDOR:
	    ret += " action=VENDOR";
	    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;
	    case ACTION_VENDOR:
		// TODO: Handle it as appropriate
		break;
	    }
	} catch (IllegalArgumentException e) {
	    throw new IllegalArgumentException("Invalid action string");
	}
    }
}
