package click.runtime.remote;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import jist.runtime.JistAPI;

import click.runtime.remote.WrapSshConnector2.AsynchRunner;

import de.mud.jta.Wrapper;
import de.mud.telnet.TelnetWrapper;

/**
 * Connects to a remote host and sets up applications like Click
 *
 * @author kurth
 */
public class WgtTelnetConnector implements RemoteConnector {

  public static int nextRequestId = 1;

  protected Wrapper telnet;

  private String user;
  private String password;
  private int port;
  private Map<Integer, AsynchRunner> mapRequests;

  public WgtTelnetConnector() {
    telnet = new TelnetWrapper();
    mapRequests = new HashMap<Integer, AsynchRunner>();
  }

  /*
   * (non-Javadoc)
   * @see click.runtime.remote.RemoteConnector#init(java.util.Properties)
   */
  public void init(Properties prop) {
    user = prop.getProperty("user", null);
    password = prop.getProperty("password", null);
    port = Integer.parseInt(prop.getProperty("port", "22"));
  }

  public void connect(String host, int port, String user, String password) throws IOException {
    telnet.connect(host, port);
    if (user != null && user.length() > 0)
      telnet.login(user, password);
    telnet.waitfor("BusyBox");
    telnet.send("export PS1=\"user@host\"");
    telnet.waitfor("user@host");
    telnet.waitfor("user@host");
    telnet.setPrompt("user@host");
    telnet.waitfor("user@host");
  }

  public void disconnect() throws IOException {
    telnet.disconnect();
  }

  /**
   * TODO how to evaluate the return code??
   *
   * @param command
   * @return
   * @throws IOException
   */
  public String execute(String command) throws IOException {
    return telnet.send(command);
  }

  public String send(String command) throws IOException {
    telnet.setPrompt(null);
    return telnet.send(command);
  }


  public static void main(String[] args) throws IOException {
    WgtTelnetConnector telnet = new WgtTelnetConnector();
    telnet.connect("192.168.3.81", 23, null, null);
    System.out.println(telnet.execute("ls -la"));
    System.out.println(telnet.execute("uname"));
    System.out.println(telnet.execute("ps"));
    telnet.disconnect();
  }

  public void connect(String host) throws IOException {
    this.connect(host, port, user, password);
  }

  public void waitFor(String substring) throws IOException {
    telnet.waitfor(substring);
  }
  
  public class AsynchRunner extends Thread implements JistAPI.DoNotRewrite {
    private int requestId;
    private String[] script;
    private String output = "";
    private IOException e;
    public AsynchRunner(int requestId, String[] script) {
      this.requestId = requestId;
      this.script = script;
    }
    public void run() {
      try {
        for (int i = 0; i < script.length; i++) {
          output += execute(script[i]);
        }
      } catch (IOException e) {
        this.e = e;
      }
    }
  }
  
  public int beginExecute(String[] script) {
    AsynchRunner thread = new AsynchRunner(nextRequestId++, script);
    mapRequests.put(thread.requestId, thread);
    thread.start();
    return thread.requestId;
  }

  public String finishExecute(int requestId) throws IOException {
    AsynchRunner runner = mapRequests.remove(requestId);
    try {
      runner.join();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    if (null != runner.e)
      throw runner.e;
    return runner.output;
  }


}
