package brn.sim.scenario.rca;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import jist.swans.Constants;
import jist.swans.misc.Util;

import org.apache.log4j.Logger;

import brn.sim.AbstractParams;
import brn.sim.builder.FieldBuilder;
import brn.sim.builder.PathLossBuilder.LogDistanceParams;
import brn.sim.builder.PathLossBuilder.ShadowingParams;

public class AarfSim extends RcaSim {

  public static final Logger log = Logger.getLogger(AarfSim.class.getName());

  public static List getSimulationSuiteOutdoorRcas() {
    List ret = new ArrayList();

    long cohTimes[] = new long[] { 1 * Constants.SECOND };
    double exps[] = new double[] { 2.7 /* , /*2.7, 3.5, 4 */};

    for (int exp = 0; exp < exps.length; exp++) {
      for (double stdDev = 8; stdDev <= 8; stdDev += 4) {
        for (int coh = 0; coh < cohTimes.length; coh++) {
          // for (int refDist = 1; refDist <= 100; refDist += 99) {
          // for (boolean distShad = true, end = false; end != true; end =
          // distShad = !distShad) {
          {
            RcaParams params = new RcaParams.AarfParams();
            params.setAppUdp(3000); // really stuff the channel from the beg.
            params.setMovingAway();
            // params.setMobility();
            params.setProtocolsUdpAodv();
            params.endTime = 250 /* s */;
            params.nodes = 2;
            params.setParamsBatch();
            params.handlerNet = true;
            params.handlerForwardGraph = false;
            params.handlerMac = false;
//            params.handlerRate = false;

            LogDistanceParams lossExp = new LogDistanceParams();
            ShadowingParams pathLoss = new ShadowingParams();

            lossExp.exponent = exps[exp];
            // lossExp.refDist = refDist;
            pathLoss.pathloss = lossExp;
            pathLoss.stdDeviation = stdDev;
            pathLoss.coherenceTime = cohTimes[coh];

            pathLoss.exponential = true; // distShad;
            ((FieldBuilder.FieldParams) params.field).pathloss = pathLoss;
            ret.add(params);
          }
//          {
//            RcaParams params = new RcaParams.AmrrParams();
//            params.setAppUdp(3000); // really stuff the channel from the beg.
//            params.setMovingAway();
//            // params.setMobility();
//            params.setProtocolsUdpAodv();
//            params.endTime = 250 /* s */;
//            params.nodes = 2;
//            params.setParamsBatch();
//            params.handlerNet = true;
//            params.handlerForwardGraph = false;
//            params.handlerRadio = true;
//
//            DistExponentialParams lossExp = new DistExponentialParams();
//            DistNewShadowingParams pathLoss = new DistNewShadowingParams();
//
//            lossExp.exponent = exps[exp];
//            // lossExp.refDist = refDist;
//            pathLoss.pathloss = lossExp;
//            pathLoss.stdDeviation = stdDev;
//            pathLoss.coherenceTime = cohTimes[coh];
//
//            pathLoss.exponential = false; // distShad;
//            ((FieldBuilder.FieldParams) params.field).pathloss = pathLoss;
//            ret.add(params);
//          }
          // }
          // }
        }
      }
    }
    return ret;
  }

  /*
   * (non-Javadoc)
   * 
   * @see brn.sim.AbstractDriver#getSimulationSuite()
   */
  public List getSimulationSuite(String version) {
    return getSimulationSuiteOutdoorRcas();
  }

  /*
   * (non-Javadoc)
   * 
   * @see brn.sim.AbstractDriver#runDistSim()
   */
  protected void runDistSim() throws Exception {
    // load properties from stdin
    Properties configuration = new Properties();
    configuration.load(System.in);

    String configFile = configuration.getProperty("driver.config");
    AbstractParams options = (AbstractParams) Util.readObject(configFile);
    if (log.isInfoEnabled())
      log.info(brn.swans.Strings.toString(options, "  "));
    // RcaParams options = RcaParams.defaultParams().setUdpAodvParams();

    options.db = true;
    options.dbJobId = Integer
        .valueOf(configuration.getProperty("simulationId")).intValue();
    options.dbDef = "jdbc:mysql://"
        + configuration.getProperty("definitions.host") + "/"
        + configuration.getProperty("definitions.database");
    options.dbRes = "jdbc:mysql://" + configuration.getProperty("results.host")
        + "/" + configuration.getProperty("results.database");
    options.dbUser = configuration.getProperty("results.username");
    options.dbPassword = configuration.getProperty("results.password");

    try {
      run(options);
    } catch (Throwable e) {
      e.printStackTrace();
      System.exit(3);
    }
  }

  /**
   * @param args
   * @throws Throwable
   */
  public static void main(String[] args) throws Throwable {
    AarfSim sim = new AarfSim();
    sim.run(args);
  }
}
