package net.onrc.onos.core.intent;

import java.util.HashSet;
import java.util.Set;

import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.core.intent.IntentOperation.Operator;
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.FlowEntryActions;
import net.onrc.onos.core.util.FlowEntryId;
import net.onrc.onos.core.util.FlowEntryUserState;

/**
 * @author Brian O'Connor <bocon@onlab.us>
 */

public class FlowEntry {
    protected long sw;
    protected Match match;
    protected Set<Action> actions;
    protected Operator operator;

    public FlowEntry(long sw, long srcPort, long dstPort,
                     MACAddress srcMac, MACAddress dstMac,
                     Operator operator) {
        this.sw = sw;
        this.match = new Match(sw, srcPort, srcMac, dstMac);
        this.actions = new HashSet<Action>();
        this.actions.add(new ForwardAction(dstPort));
        this.operator = operator;
    }

    public String toString() {
        return match + "->" + actions;
    }

    public long getSwitch() {
        return sw;
    }

    public Operator getOperator() {
        return operator;
    }

    public void setOperator(Operator op) {
        operator = op;
    }

    public net.onrc.onos.core.util.FlowEntry getFlowEntry() {
        net.onrc.onos.core.util.FlowEntry entry = new net.onrc.onos.core.util.FlowEntry();
        entry.setDpid(new Dpid(sw));
        entry.setFlowEntryId(new FlowEntryId(hashCode())); // naive, but useful for now
        entry.setFlowEntryMatch(match.getFlowEntryMatch());
        FlowEntryActions flowEntryActions = new FlowEntryActions();
        for (Action action : actions) {
            flowEntryActions.addAction(action.getFlowEntryAction());
        }
        entry.setFlowEntryActions(flowEntryActions);
        switch (operator) {
            case ADD:
                entry.setFlowEntryUserState(FlowEntryUserState.FE_USER_MODIFY);
                break;
            case REMOVE:
                entry.setFlowEntryUserState(FlowEntryUserState.FE_USER_DELETE);
                break;
            default:
                break;
        }
        return entry;
    }


    public int hashCode() {
        return match.hashCode();
    }

    public boolean equals(Object o) {
        if (!(o instanceof FlowEntry)) {
            return false;
        }
        FlowEntry other = (FlowEntry) o;
        // Note: we should not consider the operator for this comparison
        return this.match.equals(other.match)
                && this.actions.containsAll(other.actions)
                && other.actions.containsAll(this.actions);
    }
}
