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 AmrrSim extends RcaSim {

  public static final Logger log = Logger.getLogger(AmrrSim.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.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;

            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;
  }

  public static List getSimulationSuiteShadow2() {
    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 seed = 13; seed <= 23; seed++) {
            RcaParams params = new RcaParams.AmrrParams();
            params.setShadowSim2(exps[exp], stdDev, cohTimes[coh], seed);
            ret.add(params);
          }
        }
      }
    }
    return ret;
  }

  public static List getSimulationSuiteShadowTest() {
    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 seed = 1; seed <= 1; seed++) {
            RcaParams params = new RcaParams.AmrrParams();
            params.setShadowSim2(exps[exp], stdDev, cohTimes[coh], seed);
            params.endTime = 50;
            params.setMovingAway(200, 2);
            ret.add(params);
          }
        }
      }
    }
    return ret;
  }

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

		for (int seed = 1; seed <= 7; seed++) {
			RcaParams params = new RcaParams.AmrrParams();
			params.setPathlossFadingSim1(seed);

			ret.add(params);
		}

		return ret;
	}

	public static List getSimulationSuitePathloss() {
		List ret = new ArrayList();
		for (int seed = 1; seed <= 7; seed++) {
			RcaParams params = new RcaParams.AmrrParams();
			params.setPathlossSim(2.7, seed);
			ret.add(params);
		}
		return ret;
	}
	
	public static List getSimulationSuitePathlossTest() {
		List ret = new ArrayList();
		for (int seed = 1; seed <= 1; seed++) {
			RcaParams params = new RcaParams.AmrrParams();
			params.setPathlossSim(2.7, seed);
			params.setMovingAway(72, 4, .5);
			params.endTime = 15;
			ret.add(params);
		}
		return ret;
	}

	public static List getSimulationSuitePathlossShadowing() {
		List ret = new ArrayList();
		for (int seed = 1; seed <= 5; seed++) {
			for (int dist = 180; dist <= 180; dist += 50) {
				RcaParams params = new RcaParams.AmrrParams();
				params.setPathlossShadowingSim(seed, dist);
				ret.add(params);
			}
		}
		return ret;
	}
	
	public static List getSimulationSuitePathlossShadowingMoving() {
		List ret = new ArrayList();
		for (int seed = 1; seed <= 7; seed++) {
			for (int dist = 80; dist <= 130; dist += 50) {
				RcaParams params = new RcaParams.AmrrParams();
				params.setPathlossShadowingMovingSim(seed, dist);
				ret.add(params);
			}
		}
		return ret;
	}

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

  /**
   * Runs a local test defined in derived classes.
   */
  protected void runLocal() {
    try {
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  
  /*
   * (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 {
    AmrrSim sim = new AmrrSim();
    sim.run(args);
  }
}
