package brn.swans.net;

import java.util.List;

import jist.runtime.JistAPI;
import jist.runtime.JistAPI.Continuation;
import jist.swans.mac.MacAddress;
import jist.swans.misc.Message;
import jist.swans.misc.MessageAnno;
import jist.swans.net.NetAddress;
import jist.swans.net.NetInterface;
import jist.swans.net.NetMessage.Ip;

/**
 * Network layer interface for txdor.
 *
 * @author kurth
 */
public interface NetTxDORInterface extends NetInterface {

  /**
   * If there is a queued packet fitting the constraint netSrc and netId, send
   * it to mac instantly.
   *
   * @param interfaceId
   * @param src
   * @param candidates
   * @param seqNo
   * @param retry
   * @param timeToSend the absolute point in time without any turnaround.
   * @param netSrc
   * @param netId
   * @param idxFinalDst
   */
  void instantPump(byte interfaceId, MacAddress src, List candidates,
      short seqNo, boolean retry, long timeToSend, NetAddress netSrc,
      short netId, byte ttl, byte idxFinalDst);

  /**
   * The mac stopped processing the given packet. The retry field indicates
   * whether the packet should be discarded (e.g. another node had already
   * forwarded it) or re-enqueued (e.g. a time scheduled transmission interrupted
   * the processing of the current packet).
   *
   * @param netId
   * @param msg
   * @param nextHop
   * @param anno
   */
  void reenqueuePacket(byte netId, Message msg, MacAddress nextHop, MessageAnno anno);

  public static final class Dlg implements NetTxDORInterface, JistAPI.Proxiable {
    private NetTxDORInterface netInterface;

    public Dlg(NetTxDORInterface netInterface) {
      this.netInterface = netInterface;
    }

    public void endSend(Message msg, int netid, MessageAnno anno) {
      netInterface.endSend(msg, netid, anno);
    }

    public NetAddress getAddress() throws Continuation {
      return netInterface.getAddress();
    }

    public void receive(Message msg, MacAddress lastHop, byte macId, boolean promiscuous, MessageAnno anno) {
      netInterface.receive(msg, lastHop, macId, promiscuous, anno);
    }

    public void send(Ip msg, int interfaceId, MacAddress nextHop, MessageAnno anno) {
      netInterface.send(msg, interfaceId, nextHop, anno);
    }

    public void send(Message msg, NetAddress dst, short protocol, byte priority, byte ttl, MessageAnno anno) {
      netInterface.send(msg, dst, protocol, priority, ttl, anno);
    }

    public void reenqueuePacket(byte netId, Message msg, MacAddress nextHop, MessageAnno anno) {
      netInterface.reenqueuePacket(netId, msg, nextHop, anno);
    }

    public void instantPump(byte interfaceId, MacAddress src, List candidates, short seqNo, boolean retry, long timeToSend, NetAddress netSrc, short netId, byte ttl, byte idxFinalDst) {
      netInterface.instantPump(interfaceId, src, candidates, seqNo, retry, timeToSend, netSrc, netId, ttl, idxFinalDst);
    }
  }
}
