package net.floodlightcontroller.topology;

import java.util.Date;
import java.util.List;
import java.util.Set;

import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;

public interface ITopologyService extends IFloodlightService  {

    public void addListener(ITopologyListener listener);

    public Date getLastUpdateTime();

    /**
     * Query to determine if devices must be learned on a given switch port.
     */
    public boolean isAttachmentPointPort(long switchid, short port);
    public boolean isAttachmentPointPort(long switchid, short port,
                                         boolean tunnelEnabled);

    public long getOpenflowDomainId(long switchId);
    public long getOpenflowDomainId(long switchId, boolean tunnelEnabled);

    /**
     * Returns the identifier of the L2 domain of a given switch.
     * @param switchId The DPID of the switch in long form
     * @return The DPID of the switch that is the key for the cluster
     */
    public long getL2DomainId(long switchId);
    public long getL2DomainId(long switchId, boolean tunnelEnabled);

    /**
     * Queries whether two switches are in the same cluster.
     * @param switch1
     * @param switch2
     * @return true if the switches are in the same cluster
     */
    public boolean inSameOpenflowDomain(long switch1, long switch2);
    public boolean inSameOpenflowDomain(long switch1, long switch2, 
                                        boolean tunnelEnabled);

    /**
     * Queries whether two switches are in the same island.
     * Currently, island and cluster are the same. In future,
     * islands could be different than clusters.
     * @param switch1
     * @param switch2
     * @return True of they are in the same island, false otherwise
     */
    public boolean inSameL2Domain(long switch1, long switch2);
    public boolean inSameL2Domain(long switch1, long switch2, 
                                  boolean tunnelEnabled);

    public boolean isBroadcastDomainPort(long sw, short port);
    public boolean isBroadcastDomainPort(long sw, short port, 
                                         boolean tunnelEnabled);


    public boolean isAllowed(long sw, short portId);
    public boolean isAllowed(long sw, short portId, boolean tunnelEnabled);

    /**
     * Indicates if an attachment point on the new switch port is consistent
     * with the attachment point on the old switch port or not.
     */
    public boolean isConsistent(long oldSw, short oldPort,
                                long newSw, short newPort);
    public boolean isConsistent(long oldSw, short oldPort,
                                long newSw, short newPort,
                                boolean tunnelEnabled);

    /**
     * Indicates if the two switch ports are connected to the same
     * broadcast domain or not.
     * @param s1
     * @param p1
     * @param s2
     * @param p2
     * @return
     */
    public boolean isInSameBroadcastDomain(long s1, short p1, 
                                           long s2, short p2);
    public boolean isInSameBroadcastDomain(long s1, short p1,
                                           long s2, short p2,
                                           boolean tunnelEnabled);

    /**
     * Gets a list of ports on a given switch that are known to topology.
     * @param sw The switch DPID in long
     * @return The set of ports on this switch
     */
    public Set<Short> getPortsWithLinks(long sw);
    public Set<Short> getPortsWithLinks(long sw, boolean tunnelEnabled);

    /** Get broadcast ports on a target switch for a given attachmentpoint
     * point port.
     */
    public Set<Short> getBroadcastPorts(long targetSw, long src, short srcPort);

    public Set<Short> getBroadcastPorts(long targetSw, long src, short srcPort,
                                        boolean tunnelEnabled);

    /**
     * 
     */
    public boolean isIncomingBroadcastAllowed(long sw, short portId);
    public boolean isIncomingBroadcastAllowed(long sw, short portId,
                                              boolean tunnelEnabled);


    /** Get the proper outgoing switchport for a given pair of src-dst
     * switchports.
     */
    public NodePortTuple getOutgoingSwitchPort(long src, short srcPort,
                                               long dst, short dstPort);


    public NodePortTuple getOutgoingSwitchPort(long src, short srcPort,
                                               long dst, short dstPort,
                                               boolean tunnelEnabled);


    public NodePortTuple getIncomingSwitchPort(long src, short srcPort,
                                               long dst, short dstPort);
    public NodePortTuple getIncomingSwitchPort(long src, short srcPort,
                                               long dst, short dstPort,
                                               boolean tunnelEnabled);

    /**
     * If the dst is not allowed by the higher-level topology,
     * this method provides the topologically equivalent broadcast port.
     * @param src
     * @param dst
     * @return the allowed broadcast port
     */
    public NodePortTuple 
    getAllowedOutgoingBroadcastPort(long src,
                                    short srcPort,
                                    long dst,
                                    short dstPort);

    public NodePortTuple 
    getAllowedOutgoingBroadcastPort(long src,
                                    short srcPort,
                                    long dst,
                                    short dstPort,
                                    boolean tunnelEnabled);

    /**
     * If the src broadcast domain port is not allowed for incoming
     * broadcast, this method provides the topologically equivalent
     * incoming broadcast-allowed
     * src port.  
     * @param src
     * @param dst
     * @return the allowed broadcast port
     */
    public NodePortTuple
    getAllowedIncomingBroadcastPort(long src,
                                    short srcPort);

    public NodePortTuple
    getAllowedIncomingBroadcastPort(long src,
                                    short srcPort,
                                    boolean tunnelEnabled);


    /**
     * Gets the set of ports that belong to a broadcast domain.
     * @return The set of ports that belong to a broadcast domain.
     */
    public Set<NodePortTuple> getBroadcastDomainPorts();
    public Set<NodePortTuple> getTunnelPorts();


    /**
     * Returns a set of blocked ports.  The set of blocked
     * ports is the union of all the blocked ports across all
     * instances.
     * @return
     */
    public Set<NodePortTuple> getBlockedPorts();

    /**
     * ITopologyListener provides topologyChanged notification, 
     * but not *what* the changes were.  
     * This method returns the delta in the linkUpdates between the current and the previous topology instance.
     * @return
     */
    public List<LDUpdate> getLastLinkUpdates();

    /**
     * Switch methods
     */
    public Set<Short> getPorts(long sw);
}
