package com.github.jmchilton.galaxybootstrap;

import com.google.common.hash.Hashing;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class BootStrapper {
  private final DownloadProperties downloadProperties;

  public BootStrapper() {
    this(new DownloadProperties());
  }

  public BootStrapper(final DownloadProperties downloadProperties) {
    this.downloadProperties = downloadProperties;
  }

  public String getPath() {
    return downloadProperties.location.getAbsolutePath();
  }
  
  public File getRoot() {
    return new File(getPath());
  }
  
  public GalaxyDaemon run(final GalaxyProperties galaxyProperties) {
    return run(galaxyProperties, null);
  }
  
  public GalaxyDaemon run(final GalaxyProperties galaxyProperties,
                          final GalaxyData galaxyData) {
    galaxyProperties.configureGalaxy(getRoot());
    executeGalaxyScript("python scripts/fetch_eggs.py");
    executeGalaxyScript("sh create_db.sh > /dev/null");
    if(galaxyData != null) {
      galaxyData.writeSeedScript(new File(getRoot(), "seed.py"));
      executeGalaxyScript("python seed.py");
    }
    final Process process = IoUtils.execute("sh", new File(getPath(), "run.sh").getAbsolutePath(), "--daemon");
    return new GalaxyDaemon(galaxyProperties, getRoot(), this);
  }
  
  public void deleteGalaxyRoot() {
    IoUtils.executeAndWait("/bin/rm", "-rf", getPath());
  }

  public static class GalaxyDaemon {
    private final GalaxyProperties galaxyProperties;
    private final File galaxyRoot;
    private final BootStrapper bootStrapper;
    
    GalaxyDaemon(final GalaxyProperties galaxyProperties,
                 final File galaxyRoot,
                 final BootStrapper bootStrapper) {
      this.galaxyProperties = galaxyProperties;
      this.galaxyRoot = galaxyRoot;
      this.bootStrapper = bootStrapper;
    }
    
    public BootStrapper getBootStrapper() {
      return bootStrapper;
    }
    
    public void stop() {
      final Process process = IoUtils.execute("sh", new File(galaxyRoot, "run.sh").getAbsolutePath(), "--stop-daemon");
      try {
        process.waitFor();
      } catch(InterruptedException ex) {
        throw new RuntimeException(ex);
      }
    }
    
    public boolean up() {
      return !IoUtils.available(galaxyProperties.getPort());
    }
    
    public boolean waitForUp() {
      return wait(true);
    }
    
    public boolean waitForDown() {
      return wait(false);
    }
    
    private boolean wait(final boolean up) {
      boolean correctState = false;
      for(int i = 0; i < 600; i++) {
        correctState = up() == up;
        if(correctState) {
          break;
        }
        try {
          Thread.sleep(1000L);
        } catch(InterruptedException ex) {
          throw new RuntimeException(ex);
        }
      }
      return correctState;
    }

  }
  
  
  public void setupGalaxy() {
    downloadProperties.download();
  }
  
  private void executeGalaxyScript(final String scriptName) {
    final String bashScript = String.format("cd %s; %s", getPath(), scriptName);
    IoUtils.executeAndWait("bash", "-c", bashScript);
  }
  
}

@@ -234,16 +234,75 @@
 perties;
+%0A  private final String galaxyLogDirName = %22bootstrap-log%22;
 %0A%0A  publ
@@ -766,129 +766,1027 @@
  %0A  
-public GalaxyDaemon run(final GalaxyProperties galaxyProperties,%0A                          final GalaxyData galaxyData) %7B
+/**%0A   * Defines a directory to place all log files for Galaxy bootstrap.%0A   * @return  A directory to place all log files for Galaxy bootstrap.%0A   */%0A  private File getBootstrapLogDir() %7B%0A    return new File(downloadProperties.location.getPath(), galaxyLogDirName);%0A  %7D%0A  %0A  /**%0A   * Constructs a path of a file under the bootstrap log directory.%0A   * @param bootstrapLogDir  The File defining the log directory.%0A   * @param logFileName  The name of the log file.%0A   * @return  The full path to the log file.%0A   */%0A  private String buildLogPath(File bootstrapLogDir, String logFileName) %7B%0A    return new File(bootstrapLogDir, logFileName).getAbsolutePath();%0A  %7D%0A  %0A  public GalaxyDaemon run(final GalaxyProperties galaxyProperties,%0A                          final GalaxyData galaxyData) %7B%0A    File bootstrapLogDir = getBootstrapLogDir();%0A    if (!bootstrapLogDir.exists()) %7B%0A      if (!bootstrapLogDir.mkdir()) %7B%0A        throw new RuntimeException(%22Could not make log directory %22 + bootstrapLogDir);%0A      %7D%0A    %7D%0A    
 %0A   
@@ -1884,19 +1884,93 @@
 _eggs.py
-%22);
+ 1%3E %22%0A      + buildLogPath(bootstrapLogDir,%22fetch_eggs.log%22) + %22 2%3E&1%22);%0A    
 %0A    exe
@@ -2007,23 +2007,85 @@
 .sh 
+1
 %3E 
-/dev/null
+%22 %0A      + buildLogPath(bootstrapLogDir,%22create_db.log%22) + %22 2%3E&1
 %22);%0A
+    %0A
     
@@ -2216,16 +2216,82 @@
  seed.py
+ 1%3E %22 %0A        + buildLogPath(bootstrapLogDir,%22seed.log%22) + %22 2%3E&1
 %22);%0A    

Write out Galaxy command output to log files for debugging