package test.sim.scenario;

import jist.runtime.JistAPI;
import jist.swans.Constants;
import brn.sim.AbstractParams;
import brn.sim.builder.FadingBuilder;
import brn.sim.builder.FieldBuilder;
import brn.sim.builder.MacBuilder;
import brn.sim.builder.MetricBuilder;
import brn.sim.builder.NetBuilder;
import brn.sim.builder.RadioBuilder;
import brn.sim.builder.RateBuilder;
import brn.sim.builder.MetricBuilder.EtxParams;
import brn.sim.builder.PathLossBuilder.LogDistanceParams;
import brn.sim.builder.PathLossBuilder.ShadowingParams;
import brn.sim.builder.RadioBuilder.NoiseAdditiveBerParams;
import brn.sim.builder.RadioBuilder.NoiseAdditiveParams;
import brn.sim.scenario.coverage.LinkQuality;
import brn.sim.scenario.coverage.LinkQualityParams;

public class TestLinkQuality {

  public static LinkQualityParams getParams1() {
    LinkQualityParams params =
      (LinkQualityParams) TestParamBuilder.build(LinkQualityParams.class);

    params.gui = true;
    params.endTime = 500;
    params.seed = 1;
    params.nodes = 50;

    params.handlerRadio = true;
    params.handlerLinkQuality = true;
//    params.handlerRadioTimeBar = true;
//    params.handlerMacTimeBar = true;
//    params.handlerNetTimeBar = true;

    params.singeSender = true;

    MetricBuilder.EtxParams metric = new MetricBuilder.EtxParams();
    metric.period = 1000 / 2 / 60;
    metric.tau = 30000 / 4 / 60;
    metric.probes = new int[] {
        Constants.BANDWIDTH_6Mbps, 1000,
        Constants.BANDWIDTH_9Mbps, 1000,
        Constants.BANDWIDTH_12Mbps, 1000,
        Constants.BANDWIDTH_18Mbps, 1000,
        Constants.BANDWIDTH_24Mbps, 1000,
        Constants.BANDWIDTH_36Mbps, 1000,
        Constants.BANDWIDTH_48Mbps, 1000,
        Constants.BANDWIDTH_54Mbps, 1000,
    };
    metric.numberOfChannels = Constants.CHANNEL_NUMBER_DEFAULT;
    metric.autoStart = false;
    params.metric = metric;

    LogDistanceParams lossExp = new LogDistanceParams();
    lossExp.exponent = 3.5;

    ShadowingParams pathLoss = new ShadowingParams();
    pathLoss.pathloss = lossExp;
    pathLoss.stdDeviation = 4.;
    pathLoss.exponential = false; // JistAPI.END !! 
    pathLoss.coherenceTime = JistAPI.END;//(long)(2.5 * Constants.SECOND);

    FadingBuilder.PunnooseRicianParams fading = new FadingBuilder.PunnooseRicianParams();
    fading.maxVelocity = 1.5;
    fading.K = 0;

    FieldBuilder.FieldParams field = new FieldBuilder.FieldParams();
    field.fieldX = 400;
    field.fieldY = 100;
    field.spatial_mode = Constants.SPATIAL_LINEAR;
    field.pathloss = pathLoss;
    field.fading = fading;
    params.field = field;

    RadioBuilder.NoiseParams radio = 
//      new RadioBuilder.NoiseAdditiveParams();
      new RadioBuilder.NoiseAdditiveBerParams();
    radio.fieldX = field.fieldX;
    radio.fieldY = field.fieldY;
    radio.placement = Constants.PLACEMENT_GRID;
    radio.placementOpts = "" + params.nodes + "x1";
    radio.useAnnos = true;
    radio.radioType = Constants.MAC_802_11g_PURE;
    params.node.radio = radio;

    MacBuilder.M802_11Params mac = new MacBuilder.M802_11Params();
    mac.useAnnos = radio.useAnnos;
    mac.useBitRateAnnos = true;
//    mac.macType = Constants.MAC_802_11g_PURE;
    RateBuilder.ConstantParams rate = (RateBuilder.ConstantParams)mac.rateSelection;
    rate.dataBitrate = Constants.BANDWIDTH_6Mbps;
    rate.controlBitrate = rate.dataBitrate;
    params.node.mac = mac;

    NetBuilder.IpParams net = new NetBuilder.IpParams();
    net.protocolMapper = new int[] {Constants.NET_PROTOCOL_LINK_PROBE };
    params.node.net = net;

    params.node.route = null;
    return params;
  }
  
  public static LinkQualityParams getParams2() {
    LinkQualityParams params = getParams1();
    
    params.nodes = 2;
    params.endTime = 250;

    FieldBuilder.FieldParams field = (FieldBuilder.FieldParams) params.field;
    field.fieldX = 400;
    field.fieldY = 100;
    field.mobility = Constants.MOBILITY_BOUNDLESS_SIM_AREA;
    field.mobilityOpts = "1:1:0:0:.5:0:1:0";
    
    NoiseAdditiveBerParams radio = (NoiseAdditiveBerParams) params.node.radio; 
//    radio.recvCorruptPackets = false;
//    NoiseAdditiveParams radio = (NoiseAdditiveParams) params.node.radio; 
    radio.fieldX = field.fieldX;
    radio.fieldY = field.fieldY;
    radio.placement = Constants.PLACEMENT_MANUAL;
    radio.placementOpts = "0x50:0x51";
    radio.startMobility = "-1:0";

    MetricBuilder.EtxParams metric = (EtxParams) params.metric;
    metric.period = 1000 / 2 / 60;
    metric.tau = 30000 / 4 / 60;

    return params;
  }
  
  public static void main(String[] args) throws Exception {
    LinkQuality test = new LinkQuality();
    AbstractParams params = getParams2();
//    params.fileBinary = true;
//    params.directory = "./tmp/";
    test.run(params);
  }

}
