package brn.swans.net;

import jist.runtime.JistAPI;
import jist.swans.Constants;
import jist.swans.mac.Mac802_11e;
import jist.swans.mac.MacInterface.IMacEDcf;
import jist.swans.misc.Mapper;
import jist.swans.misc.Message;
import jist.swans.misc.MessageAnno;
import jist.swans.net.NetAddress;
import jist.swans.net.NetIp;
import jist.swans.net.NetMessage;
import jist.swans.net.PacketLoss;
import jist.swans.net.QueuedMessage;
import jist.swans.net.NetIp.NicInfo;


public class NetQoS extends NetIp {

  public NetQoS(NetAddress addr, Mapper protocolMap, PacketLoss in,
      PacketLoss out) {
    super(addr, protocolMap, in, out);
    // TODO Auto-generated constructor stub
  }

  public void endSend(Message msg, int interfaceId, MessageAnno anno) {
//    super.endSend(msg, interfaceId, anno);
 // log the feedback event
    if (msg != null) {
      if (sendToMacFinishEvent.isActive()) {
        sendToMacFinishEvent.handle(msg, anno, localAddr);
      }
    }

    NicInfo ni = nics[interfaceId];
    if(ni.q.isEmpty())
    {
      ni.busy = false;
    }
    else
    {
      short ac = Mac802_11e.priorityToAccessCategory(
          ((NetMessage.Ip)ni.q.get().getPayload()).getPriority());
      
      IMacEDcf mac = (IMacEDcf) ni.mac;
//      if (mac.isQueueFull(ac)) {
//        ni.q.remove();
//        return;
//      }
      
      ni.busy = true;
      QueuedMessage qmsg = ni.q.remove();
      NetMessage.Ip ip = (NetMessage.Ip)qmsg.getPayload();
      ip = ip.freeze(); // immutable once packet leaves node
      
      if (dequeueEvent.isActive())
        dequeueEvent.handle(ip, qmsg.getAnno(), localAddr, qmsg.getNextHop(), ni.q);
      if (sendToMacEvent.isActive())
        sendToMacEvent.handle(ip, qmsg.getAnno(), localAddr, qmsg.getNextHop());

      // jittering on network layer
      // after event stuff because otherwise the ordering gets confused
      JistAPI.sleep(netMinDelay +
          (long) (Constants.random.nextDouble() * (netMaxDelay - netMinDelay)));

      if(log.isInfoEnabled())
        log.info("send t="+JistAPI.getTime()+" to="+qmsg.getNextHop()+" data="+ip);

      ni.mac.send(ip, qmsg.getNextHop(), qmsg.getAnno());
    }
  }
}
