package brn.sim.scenario.rca;

import java.util.ArrayList;
import java.util.Comparator;
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;

public class ConstantRateSim extends RcaSim {

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

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

    RcaParams params = new RcaParams().setMovingAway();

    int[] bitrates = Constants.BITRATES_OFDM;
    for (int i = 0; i < bitrates.length; i++) {
      RcaParams pars = new RcaParams.ConstParams(bitrates[i], bitrates[i]);
      pars.setProtocolsUdpAodv();
      pars.endTime = 150 /* s */;
      pars.nodes = 2;
      // ret.add(params);
      pars.setParamsBatch();
      pars.handlerNet = true;
      pars.field = params.field;
      pars.node.radio = params.node.radio;
      ret.add(pars);
    }

    // for (int distance = 0; distance <= 400; distance += 40) {
    // ((FieldBuilder.FieldParams)params.field).fieldX = distance;
    // ((RadioBuilder.NoiseParams)params.node.radio).fieldX = distance;
    // if (log.isInfoEnabled())
    // log.info(brn.swans.Strings.toString(params, " "));
    // ret.add(params);
    // }

    // parameter density
    // for (int nodes = 2; nodes <= 2; nodes *= 2) {
    // for (int seed = 1; seed <= 1; seed++) {
    // for (double exp = 2.7; exp <= 3.6; exp += 1) {
    // double exp = 2.7;
    // for (int stdDev = 4; stdDev <= 4; stdDev += 4) {
    // // for (int cohere = 0; cohere <= 1000; cohere += 250) {
    // DistShadowingParams pathLoss = (DistShadowingParams)
    // ((FieldBuilder.FieldParams) params.field).pathloss;
    // pathLoss.exponent = exp;
    // pathLoss.stdDeviation = stdDev;
    // pathLoss.coherenceTime = 1000 * Constants.MILLI_SECOND;
    // ret.add(params);
    // }
    // }
    // }
    // }

    return ret;
  }

  public static List getSimulationSuiteConstant() {
    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) {
          for (int seed = 1; seed <= 5; seed++) {
            for (int rix = 0 /* Constants.BITRATES_ALL.length - 5 */; rix < Constants.BITRATES_ALL.length - 5; rix++) {
              {
                int controlRate = Constants.BITRATES_OFDM[0];
                if (Util.isInArray(Constants.BITRATES_DSSS,
                    Constants.BITRATES_ALL[rix]) >= 0)
                  controlRate = Constants.BITRATES_DSSS[0];
                RcaParams params = new RcaParams.ConstParams(
                    Constants.BITRATES_ALL[rix], controlRate);

                params.setShadowSim1(exps[exp], stdDev, cohTimes[coh], seed);
                ret.add(params);
              }
            }
          }
          // }
          // }
        }
      }
    }
    return ret;
  }

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

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

    // Enumeration keys = configuration.keys();
    // while (keys.hasMoreElements()) {
    // String key = (String) keys.nextElement();
    // log.warn(key + " = " + configuration.getProperty(key));
    // }

    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 {
    ConstantRateSim sim = new ConstantRateSim();
    sim.run(args);
  }

  protected void evalSimulationResults(String dbUrl, String dbUser,
      String dbPasswd, String driver, String version, String dbResUrl,
      String dbResUser, String dbResPasswd) throws Throwable {
    Evaluator e = new Evaluator();
    e.evalSimulationResults(dbUrl, dbUser, dbPasswd, driver, version, dbResUrl,
        dbResUser, dbResPasswd);
  }

  public static class C implements Comparator {

    public int compare(Object arg0, Object arg1) {
      double[][] a1 = (double[][]) arg0;
      double[][] a2 = (double[][]) arg1;
      return (int) (a2[1][1] - a1[1][1]);
    }
  }

}
