package water.deploy;

import java.io.File;
import java.util.ArrayList;
import java.util.Set;

import water.H2O;
import water.util.Log;
import water.util.Utils;

public class Host {
  public static final String SSH_OPTS;

  static {
    SSH_OPTS = "" //
        + " -o UserKnownHostsFile=/dev/null" //
        + " -o StrictHostKeyChecking=no" //
        + " -o LogLevel=quiet" //
        + " -o ServerAliveInterval=15" //
        + " -o ServerAliveCountMax=3";
  }

  public static final String FOLDER = "h2o_rsync";
  private final String _address, _user, _key;

  public Host(String addr) {
    this(addr, null);
  }

  public Host(String addr, String user) {
    this(addr, user, null);
  }

  public Host(String addr, String user, String key) {
    _address = addr;
    _user = user != null ? user : System.getProperty("user.name");
    _key = key;
  }

  public String address() {
    return _address;
  }

  public String user() {
    return _user;
  }

  public String key() {
    return _key;
  }

  public void rsync(Set<String> includes, Set<String> excludes, boolean delete) {
    rsync(includes, excludes, delete, FOLDER);
  }

  public void rsync(Set<String> includes, Set<String> excludes, boolean delete, String folder) {
    Process process = null;
    try {
      ArrayList<String> args = new ArrayList<String>();
      args.add("rsync");
      args.add("-vrzute");
      args.add(sshWithArgs());
      args.add("--chmod=u=rwx");

      for( String s : includes )
        args.add(new File(s).getCanonicalPath());

      // --exclude seems ignored on Linux (?) so use --exclude-from
      File file = Utils.writeFile(Utils.join('\n', excludes));
      args.add("--exclude-from");
      args.add(file.getCanonicalPath());
      if( delete )
        args.add("--delete");

      args.add(_address + ":" + "/home/" + _user + "/" + folder);
      ProcessBuilder builder = new ProcessBuilder(args);
      process = builder.start();
      String log = "rsync " + H2O.findInetAddressForSelf() + " -> " + _address;
      NodeVM.inheritIO(process, Log.padRight(log + ": ", 24));
      process.waitFor();
    } catch( Exception ex ) {
      throw new RuntimeException(ex);
    } finally {
      if( process != null ) {
        try {
          process.destroy();
        } catch( Exception _ ) {
          // Ignore
        }
      }
    }
  }

  public static void rsync(final Host[] hosts, final Set<String> includes, final Set<String> excludes,
      final boolean delete) {
    ArrayList<Thread> threads = new ArrayList<Thread>();

    for( int i = 0; i < hosts.length; i++ ) {
      final int i_ = i;
      Thread t = new Thread() {
        @Override public void run() {
          hosts[i_].rsync(includes, excludes, delete);
        }
      };
      t.setDaemon(true);
      t.start();
      threads.add(t);
    }

    for( Thread t : threads ) {
      try {
        t.join();
      } catch( InterruptedException e ) {
        throw Log.errRTExcept(e);
      }
    }
  }

  String sshWithArgs() {
    String k = "";
    if( _key != null ) {
      assert new File(_key).exists();
      // Git doesn't set permissions, so force them each time
      try {
        Process p = Runtime.getRuntime().exec("chmod 600 " + _key);
        p.waitFor();
      } catch( Exception e ) {
        throw Log.errRTExcept(e);
      }
      k = " -i " + _key;
    }
    return "ssh -l " + _user + " -A" + k + SSH_OPTS;
  }

  @Override public String toString() {
    return "Host " + _address;
  }
}

@@ -1818,14 +1818,9 @@
  + %22
-/home/
+~
 %22 + 

Use ~user instead of /home/user/