package net.onrc.onos.core.util;


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

/**
 * The class representing the Flow Entry.
 *
 * NOTE: The specification is incomplete. E.g., the entry needs to
 * support multiple in-ports and multiple out-ports.
 */
public class FlowEntry {
    private FlowId flowId;			// FlowID of the Flow Entry
    private FlowEntryId flowEntryId;		// The Flow Entry ID
    private int		idleTimeout;		// The Flow idle timeout
    private int		hardTimeout;		// The Flow hard timeout
    private int		priority;		// The Flow priority
    private FlowEntryMatch flowEntryMatch;	// The Flow Entry Match
    private FlowEntryActions flowEntryActions;	// The Flow Entry Actions
    private Dpid dpid;				// The Switch DPID
    private Port inPort;		// The Switch incoming port. Used only
					// when the entry is used to return
					// Shortest Path computation.
    private Port outPort;		// The Switch outgoing port. Used only
					// when the entry is used to return
					// Shortest Path computation.
    private FlowEntryUserState flowEntryUserState; // The Flow Entry User state
    private FlowEntrySwitchState flowEntrySwitchState; // The Flow Entry Switch state
    // The Flow Entry Error state (if FlowEntrySwitchState is FE_SWITCH_FAILED)
    private FlowEntryErrorState flowEntryErrorState;

    /**
     * Default constructor.
     */
    public FlowEntry() {
	// TODO: Test code
	/*
	MACAddress mac = MACAddress.valueOf("01:02:03:04:05:06");
	IPv4 ipv4 = new IPv4("1.2.3.4");
	IPv4Net ipv4net = new IPv4Net("5.6.7.0/24");

	flowEntryMatch = new FlowEntryMatch();
	flowEntryMatch.enableInPort(new Port((short)10));
	flowEntryMatch.enableSrcMac(mac);
	flowEntryMatch.enableDstMac(mac);
	flowEntryMatch.enableVlanId((short)20);
	flowEntryMatch.enableVlanPriority((byte)30);
	flowEntryMatch.enableEthernetFrameType((short)40);
	flowEntryMatch.enableIpToS((byte)50);
	flowEntryMatch.enableIpProto((byte)60);
	flowEntryMatch.enableSrcIPv4Net(ipv4net);
	flowEntryMatch.enableDstIPv4Net(ipv4net);
	flowEntryMatch.enableSrcTcpUdpPort((short)70);
	flowEntryMatch.enableDstTcpUdpPort((short)80);

	FlowEntryAction action = null;
	FlowEntryActions actions = new FlowEntryActions();

	action = new FlowEntryAction();
	action.setActionOutput(new Port((short)12));
	actions.addAction(action);

	action = new FlowEntryAction();
	action.setActionOutputToController((short)13);
	actions.addAction(action);

	action = new FlowEntryAction();
	action.setActionSetVlanId((short)14);
	actions.addAction(action);

	action = new FlowEntryAction();
	action.setActionSetVlanPriority((byte)15);
	actions.addAction(action);

	action = new FlowEntryAction();
	action.setActionStripVlan(true);
	actions.addAction(action);

	action = new FlowEntryAction();
	action.setActionSetEthernetSrcAddr(mac);
	actions.addAction(action);

	action = new FlowEntryAction();
	action.setActionSetEthernetDstAddr(mac);
	actions.addAction(action);

	action = new FlowEntryAction();
	action.setActionSetIPv4SrcAddr(ipv4);
	actions.addAction(action);

	action = new FlowEntryAction();
	action.setActionSetIPv4DstAddr(ipv4);
	actions.addAction(action);

	action = new FlowEntryAction();
	action.setActionSetIpToS((byte)16);
	actions.addAction(action);

	action = new FlowEntryAction();
	action.setActionSetTcpUdpSrcPort((short)17);
	actions.addAction(action);

	action = new FlowEntryAction();
	action.setActionSetTcpUdpDstPort((short)18);
	actions.addAction(action);

	action = new FlowEntryAction();
	action.setActionEnqueue(new Port((short)19), 20);
	actions.addAction(action);

	setFlowEntryActions(actions);
	*/

	priority = FlowPath.PRIORITY_DEFAULT;
	flowEntryActions = new FlowEntryActions();
	flowEntryUserState = FlowEntryUserState.FE_USER_UNKNOWN;
	flowEntrySwitchState = FlowEntrySwitchState.FE_SWITCH_UNKNOWN;
    }

    /**
     * Get the Flow ID.
     *
     * @return the Flow ID.
     */
    @JsonIgnore
    public FlowId flowId() { return flowId; }

    /**
     * Set the Flow ID.
     *
     * @param flowId the Flow ID to set.
     */
    public void setFlowId(FlowId flowId) {
	this.flowId = flowId;
    }

    /**
     * Test whether the Flow ID is valid.
     *
     * @return true if the Flow ID is valid, otherwise false.
     */
    @JsonIgnore
    public boolean isValidFlowId() {
	if (this.flowId == null)
	    return false;
	return (this.flowId.isValid());
    }

    /**
     * Get the Flow Entry ID.
     *
     * @return the Flow Entry ID.
     */
    @JsonProperty("flowEntryId")
    public FlowEntryId flowEntryId() { return flowEntryId; }

    /**
     * Set the Flow Entry ID.
     *
     * @param flowEntryId the Flow Entry ID to set.
     */
    @JsonProperty("flowEntryId")
    public void setFlowEntryId(FlowEntryId flowEntryId) {
	this.flowEntryId = flowEntryId;
    }

    /**
     * Test whether the Flow Entry ID is valid.
     *
     * @return true if the Flow Entry ID is valid, otherwise false.
     */
    @JsonIgnore
    public boolean isValidFlowEntryId() {
	if (this.flowEntryId == null)
	    return false;
	return (this.flowEntryId.isValid());
    }

    /**
     * Get the flow idle timeout in seconds.
     *
     * It should be an unsigned integer in the interval [0, 65535].
     * If zero, the timeout is not set.
     *
     * @return the flow idle timeout.
     */
    @JsonProperty("idleTimeout")
    public int idleTimeout() { return idleTimeout; }

    /**
     * Set the flow idle timeout in seconds.
     *
     * It should be an unsigned integer in the interval [0, 65535].
     * If zero, the timeout is not set.
     *
     * @param idleTimeout the flow idle timeout to set.
     */
    @JsonProperty("idleTimeout")
    public void setIdleTimeout(int idleTimeout) {
	this.idleTimeout = 0xffff & idleTimeout;
    }

    /**
     * Get the flow hard timeout in seconds.
     *
     * It should be an unsigned integer in the interval [0, 65535].
     * If zero, the timeout is not set.
     *
     * @return the flow hard timeout.
     */
    @JsonProperty("hardTimeout")
    public int hardTimeout() { return hardTimeout; }

    /**
     * Set the flow hard timeout in seconds.
     *
     * It should be an unsigned integer in the interval [0, 65535].
     * If zero, the timeout is not set.
     *
     * @param hardTimeout the flow hard timeout to set.
     */
    @JsonProperty("hardTimeout")
    public void setHardTimeout(int hardTimeout) {
	this.hardTimeout = 0xffff & hardTimeout;
    }

    /**
     * Get the flow priority.
     *
     * It should be an unsigned integer in the interval [0, 65535].
     *
     * @return the flow priority.
     */
    @JsonProperty("priority")
    public int priority() { return priority; }

    /**
     * Set the flow priority.
     *
     * It should be an unsigned integer in the interval [0, 65535].
     *
     * @param priority the flow priority to set.
     */
    @JsonProperty("priority")
    public void setPriority(int priority) {
	this.priority = 0xffff & priority;
    }

    /**
     * Get the Flow Entry Match.
     *
     * @return the Flow Entry Match.
     */
    @JsonProperty("flowEntryMatch")
    public FlowEntryMatch flowEntryMatch() { return flowEntryMatch; }

    /**
     * Set the Flow Entry Match.
     *
     * @param flowEntryMatch the Flow Entry Match to set.
     */
    @JsonProperty("flowEntryMatch")
    public void setFlowEntryMatch(FlowEntryMatch flowEntryMatch) {
	this.flowEntryMatch = flowEntryMatch;
    }

    /**
     * Get the Flow Entry Actions.
     *
     * @return the Flow Entry Actions.
     */
    @JsonProperty("flowEntryActions")
    public FlowEntryActions flowEntryActions() {
	return flowEntryActions;
    }

    /**
     * Set the Flow Entry Actions.
     *
     * @param flowEntryActions the Flow Entry Actions to set.
     */
    @JsonProperty("flowEntryActions")
    public void setFlowEntryActions(FlowEntryActions flowEntryActions) {
	this.flowEntryActions = flowEntryActions;
    }

    /**
     * Get the Switch DPID.
     *
     * @return the Switch DPID.
     */
    @JsonProperty("dpid")
    public Dpid dpid() { return dpid; }

    /**
     * Set the Switch DPID.
     *
     * @param dpid the Switch DPID to set.
     */
    @JsonProperty("dpid")
    public void setDpid(Dpid dpid) {
	this.dpid = dpid;
    }

    /**
     * Get the Switch incoming port.
     *
     * Used only when the entry is used to return Shortest Path computation.
     *
     * @return the Switch incoming port.
     */
    @JsonProperty("inPort")
    public Port inPort() { return inPort; }

    /**
     * Set the Switch incoming port.
     *
     * Used only when the entry is used to return Shortest Path computation.
     *
     * @param inPort the Switch incoming port to set.
     */
    @JsonProperty("inPort")
    public void setInPort(Port inPort) {
	this.inPort = inPort;
    }

    /**
     * Get the Switch outgoing port.
     *
     * Used only when the entry is used to return Shortest Path computation.
     *
     * @return the Switch outgoing port.
     */
    @JsonProperty("outPort")
    public Port outPort() { return outPort; }

    /**
     * Set the Switch outgoing port.
     *
     * Used only when the entry is used to return Shortest Path computation.
     *
     * @param outPort the Switch outgoing port to set.
     */
    @JsonProperty("outPort")
    public void setOutPort(Port outPort) {
	this.outPort = outPort;
    }

    /**
     * Get the Flow Entry User state.
     *
     * @return the Flow Entry User state.
     */
    @JsonProperty("flowEntryUserState")
    public FlowEntryUserState flowEntryUserState() {
	return flowEntryUserState;
    }

    /**
     * Set the Flow Entry User state.
     *
     * @param flowEntryUserState the Flow Entry User state to set.
     */
    @JsonProperty("flowEntryUserState")
    public void setFlowEntryUserState(FlowEntryUserState flowEntryUserState) {
	this.flowEntryUserState = flowEntryUserState;
    }

    /**
     * Get the Flow Entry Switch state.
     *
     * The Flow Entry Error state is used if FlowEntrySwitchState is
     * FE_SWITCH_FAILED.
     *
     * @return the Flow Entry Switch state.
     */
    @JsonProperty("flowEntrySwitchState")
    public FlowEntrySwitchState flowEntrySwitchState() {
	return flowEntrySwitchState;
    }

    /**
     * Set the Flow Entry Switch state.
     *
     * The Flow Entry Error state is used if FlowEntrySwitchState is
     * FE_SWITCH_FAILED.
     *
     * @param flowEntrySwitchState the Flow Entry Switch state to set.
     */
    @JsonProperty("flowEntrySwitchState")
    public void setFlowEntrySwitchState(FlowEntrySwitchState flowEntrySwitchState) {
	this.flowEntrySwitchState = flowEntrySwitchState;
    }

    /**
     * Get the Flow Entry Error state.
     *
     * @return the Flow Entry Error state.
     */
    @JsonProperty("flowEntryErrorState")
    public FlowEntryErrorState flowEntryErrorState() {
	return flowEntryErrorState;
    }

    /**
     * Set the Flow Entry Error state.
     *
     * @param flowEntryErrorState the Flow Entry Error state to set.
     */
    @JsonProperty("flowEntryErrorState")
    public void setFlowEntryErrorState(FlowEntryErrorState flowEntryErrorState) {
	this.flowEntryErrorState = flowEntryErrorState;
    }

    /**
     * Convert the flow entry to a string.
     *
     * The string has the following form:
     *  [flowEntryId=XXX idleTimeout=XXX hardTimeout=XXX priority=XXX
     *   flowEntryMatch=XXX flowEntryActions=XXX dpid=XXX
     *   inPort=XXX outPort=XXX flowEntryUserState=XXX flowEntrySwitchState=XXX
     *   flowEntryErrorState=XXX]
     * @return the flow entry as a string.
     */
    @Override
    public String toString() {
	StringBuilder ret = new StringBuilder();
	if ( flowEntryId != null ) {
		ret.append("[flowEntryId=" + this.flowEntryId.toString());
	} else {
		ret.append("[");
	}
	if ( flowId != null ) {
		ret.append(" flowId=" + this.flowId.toString());
	}
	ret.append(" idleTimeout=" + this.idleTimeout);
	ret.append(" hardTimeout=" + this.hardTimeout);
	ret.append(" priority=" + this.priority);
	if ( flowEntryMatch != null ) {
		ret.append(" flowEntryMatch=" + this.flowEntryMatch.toString());
	}
	ret.append(" flowEntryActions=" + this.flowEntryActions.toString() );
	if ( dpid != null ) {
		ret.append(" dpid=" + this.dpid.toString());
	}
	if ( inPort != null ) {
		ret.append(" inPort=" + this.inPort.toString());
	}
	if ( outPort != null ) {
		ret.append(" outPort=" + this.outPort.toString());
	}
	ret.append(" flowEntryUserState=" + this.flowEntryUserState);
	ret.append(" flowEntrySwitchState=" + this.flowEntrySwitchState);
	if ( flowEntryErrorState != null ) {
		ret.append(" flowEntryErrorState=" + this.flowEntryErrorState.toString());
	}
	ret.append("]");

	return ret.toString();
    }
}
