package net.onrc.onos.ofcontroller.util;

import java.util.ArrayList;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;

/**
 * The class representing multiple Flow Entry actions.
 *
 * A set of Flow Entry actions need to be applied to each packet.
 */
public class FlowEntryActions {
    private ArrayList<FlowEntryAction> actions;	// The Flow Entry Actions

    /**
     * Default constructor.
     */
    public FlowEntryActions() {
	actions = new ArrayList<FlowEntryAction>();
    }

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

    /**
     * Copy constructor.
     *
     * @param other the object to copy from.
     */
    public FlowEntryActions(FlowEntryActions other) {
	actions = new ArrayList<FlowEntryAction>();

	for (FlowEntryAction action : other.actions) {
	    FlowEntryAction newAction = new FlowEntryAction(action);
	    actions.add(newAction);
	}
    }

    /**
     * Get the Flow Entry Actions.
     *
     * @return the Flow Entry Actions.
     */
    @JsonProperty("actions")
    public ArrayList<FlowEntryAction> actions() {
	return actions;
    }

    /**
     * Set the Flow Entry Actions.
     *
     * @param actions the Flow Entry Actions to set.
     */
    @JsonProperty("actions")
    public void setActions(ArrayList<FlowEntryAction> actions) {
	this.actions = actions;
    }

    /**
     * Add a Flow Entry Action.
     *
     * @param flowEntryAction the Flow Entry Action to add.
     */
    public void addAction(FlowEntryAction flowEntryAction) {
	actions.add(flowEntryAction);
    }

    /**
     * Test whether the set of actions is empty.
     *
     * @return true if the set of actions is empty, otherwise false.
     */
    @JsonIgnore
    public Boolean isEmpty() {
	return actions.isEmpty();
    }

    /**
     * Convert the set of actions to a string.
     *
     * The string has the following form:
     *  [[type=XXX action=XXX];[type=XXX action=XXX];...;]
     *
     * @return the set of actions as a string.
     */
    @Override
    public String toString() {
	String ret = "[";
	for (FlowEntryAction action : actions) {
	    ret += action.toString() + ";";
	}
	ret += "]";

	return ret;
    }

    /**
     * Convert a string to a set of actions.
     *
     * The string has the following form:
     *  [[type=XXX action=XXX];[type=XXX action=XXX];...;]
     *
     * @param actionsStr the set of actions as a string.
     */
    public void fromString(String actionsStr) {
	String decode = actionsStr;

	actions = new ArrayList<FlowEntryAction>();

	if (decode.isEmpty())
	    return;		// Nothing to do

	// Remove the '[' and ']' in the beginning and the end of the string
	if ((decode.length() > 1) && (decode.charAt(0) == '[') &&
	    (decode.charAt(decode.length() - 1) == ']')) {
	    decode = decode.substring(1, decode.length() - 1);
	} else {
	    throw new IllegalArgumentException("Invalid action string");
	}

	// Split the string, and decode each action
	String[] parts = decode.split(";");
	for (int i = 0; i < parts.length; i++) {
	    decode = parts[i];
	    if ((decode == null) || decode.isEmpty())
		continue;
	    FlowEntryAction flowEntryAction = null;
	    try {
		flowEntryAction = new FlowEntryAction(decode);
	    } catch (IllegalArgumentException e) {
		// TODO: Ignore invalid actions for now
		continue;
	    }
	    if (flowEntryAction != null)
		actions.add(flowEntryAction);
	}
    }
}
