package test.brn;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;

import jist.swans.misc.Util;
import brn.distsim.client.data.Group;
import brn.distsim.client.data.GroupConfigurationFiles;
import brn.distsim.client.data.GroupResultsFiles;
import brn.distsim.client.data.Package;
import brn.distsim.client.data.Simulation;
import brn.distsim.client.data.Study;
import brn.distsim.client.data.StudyPackages;
import brn.sim.AbstractParams;
import brn.sim.SimulationSuite;

public class NetcodingDistsim {

  private Connection definitions;

  private String antBuildFile = "build-distsim.xml";

  private String logPropFile = "src/jist.properties";

  public NetcodingDistsim(String url, String user, String password)
      throws ClassNotFoundException, SQLException, IOException {
    Class.forName("com.mysql.jdbc.Driver");
    definitions = DriverManager.getConnection(url, user, password);
  }

  protected Study createStudy(String name, String version, Map packages)
      throws SQLException, IOException {

    Study study = new Study(definitions, name, version,
        "ant -f build-distsim.xml " + "run"
            + " -Drun.config=jist.properties -Drun.class=test.click.NetcodingTest"
            + " -Drun.args=--distsim");
    study.performDbInsert(0);

    StudyPackages pack = study.getPackages();
    Iterator packageVersions = packages.keySet().iterator();
    while (packageVersions.hasNext()) {
      String pkg = (String) packageVersions.next();
      pack.put(pack.new Package(pkg, (String) packages.get(pkg), "package"));
    }

    pack.commit();
    return study;
  }

  protected void addGroup(Study study, int number, AbstractParams params,
      String logProperties) throws SQLException, IOException {
    String name = "group-" + number;

    Group group = new Group(definitions, name, study.getId());
    study.add(group);
    study.commit();

    GroupConfigurationFiles files = group.getConfigurationFiles();
    String remotePath = "config-" + number + ".xml";
    String config = Util.encodeObject(params);
    files.put(files.new File(remotePath, config, true));
    files.put(files.new File("jist.properties", logProperties));
    files.put(files.new File("build-distsim.xml", antBuildFile));
    files.commit();

    GroupResultsFiles resFiles = group.getResultsFiles();
    resFiles.put(resFiles.new File("stdout.txt"));
    resFiles.commit();

    Simulation simulation = new Simulation(definitions, group.getId());
    group.add(simulation);

    Properties props = new Properties();
    props.put("driver.config", remotePath);
    simulation.put(props);

    group.commit();
  }

  public void defineAll(String name, String baseUrl, String studyVersion, String jistVersion, 
      String clickVersion, boolean defineJist, boolean defineClick) 
  throws Throwable {
    List lstSimulations = null;
    String className = "test.click.NetcodingTest";
    Class testClass = Class.forName(className);

    SimulationSuite driver = (SimulationSuite) testClass.newInstance();
    lstSimulations = driver.getSimulationSuite(studyVersion);

    if (null == lstSimulations || lstSimulations.size() == 0) {
      throw new Exception(
          "Class "
              + getClass().getSimpleName()
              + " does "
              + "not define a simulation suite. Please overwrite getSimulationSuite()");
    }

    Random random = new Random(1);

    Map packages = new HashMap();
    if (defineJist) {
      Package p = new Package(definitions, "jist-swans", jistVersion, "all", baseUrl
        + "/jist-swans_" + jistVersion + "_all.zip");
      p.performDbInsert();
    }
    if (defineClick) {
      Package p = new Package(definitions, "click", clickVersion, "i386-Linux", baseUrl
          + "/click_" + clickVersion + "_i386-Linux.zip");
      p.performDbInsert();
      p = new Package(definitions, "click", clickVersion, "amd64-Linux", baseUrl
          + "/click_" + clickVersion + "_amd64-Linux.zip");
      p.performDbInsert();
    }
    packages.put("click", clickVersion);
    packages.put("jist-swans", jistVersion);

    Study study = createStudy(name, studyVersion, packages);

    int i = 1;
    while (!lstSimulations.isEmpty()) {
      int next = random.nextInt(lstSimulations.size());
      AbstractParams params = (AbstractParams) lstSimulations.remove(next);
      addGroup(study, i++, params, logPropFile);
    }
  }

  

}
