package brn.sim.scenario.mchannel;

import jist.swans.Constants;
import jist.swans.Node;
import jist.swans.misc.MessageAnno;
import jist.swans.misc.Util;
import jist.swans.net.NetAddress;
import jist.swans.net.NetIp;
import jist.swans.radio.RadioInterface;
import jist.swans.trans.TransUdp;
import jist.swans.trans.AbstractTrans;
import test.sim.handler.McExORTestEventHandler;
import brn.sim.AbstractDriver;
import brn.sim.AbstractParams;
import brn.sim.handler.TimeBarRadioPacketHandler;
import brn.sim.handler.TimeBarMacStateHandler;
import brn.sim.handler.TimeBarRadioChannelHandler;
import brn.sim.handler.LinkQualityHandler;
import brn.sim.builder.*;
import brn.swans.app.UdpApplication;

public class McExORSim extends AbstractDriver {

  protected void installHandlers(AbstractParams options) throws Exception {
    super.installHandlers(options);

    McExORParams opts = (McExORParams)options;
    if (opts.handlerRadioTimeBar) {
      int chNumber = ((FieldBuilder.FieldParams)opts.field).channelNumber;
      if (chNumber > 1) {
        TimeBarRadioChannelHandler chhandler = new TimeBarRadioChannelHandler();
        chhandler.registerHandlers();
        dataManager.add(chhandler);
      }
    }

    Object linkQualityObj = dataManager.getContributor(LinkQualityHandler.ID);

    if (linkQualityObj != null) {
      double sampleLen = ((MetricBuilder.EtxParams)((RouteBuilder.MCExORParams)opts.node.route).metric).tau;
      ((LinkQualityHandler)(linkQualityObj)).setSampleLen(/*to sec*/ sampleLen / 1000);
    }

    McExORTestEventHandler jeh = new McExORTestEventHandler();
    jeh.registerHandlers();
  }

  protected void setupApplication(AbstractParams opts, int nodeId, Node node) throws BuilderException {
    super.setupApplication(opts, nodeId, node);

    McExORParams params = (McExORParams)opts;

    { // transport
      Builder builder = builderProvider.getBuilder(params.udpParams);
      AbstractTrans trans = (AbstractTrans) builder.build(params.udpParams, node);
      builderProvider.addHookUp(builder, params.udpParams, node, trans);
      node.addTransport(trans);
    }

    { // app
      Builder builder = builderProvider.getBuilder(params.appParams);
      UdpApplication app = (UdpApplication) builder.build(params.appParams, node);
      if (null != app) {
        builderProvider.addHookUp(builder, params.appParams, node, app);
        node.addApplication(app);
      }
    }

  }

  public static void main(String[] args) {
    McExORSim test = new McExORSim();

    if (args.length < 1) {
      test.showUsage();
      return;
    }

    try {
      McExORParams options = McExORParams.defaultParams();
      //McExORParams options = McExORParams.maxThroughputParams();
      //McExORParams options = McExORParams.randomPlacementParams();

      test.run(options);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

}
