var exec = require('child_process').exec;

export class SSH {
	function initialize(options) {
		options = options || {};

		this.name    = options.name; 
    this.port    = options.port;
		this.sshOpts = (options.sshOpts || []).join(' ');
	}

	function getProc(cmd) {
    var cmd =  ['ssh', this.sshOpts, this.name, JSON.stringify(cmd) ].join(' ');
    return exec(cmd);
	}

	function exec(cmd, cb) {
		var proc = this.getProc(cmd);

		if (cb) {
			var stdout = "";
			var stderr = "";

			proc.stdout.on('data', #{ stdout += $1.toString() });
			proc.stderr.on('data', #{ stderr += $1.toString() });

			proc.on('exit', #{ cb(null, stdout, stderr) });
		}

		return new Stream(proc, this.name);
	}
}

class Stream {
  include $m.EventEmitter;

  private {
    var TIMEOUT = 60 * 30 * 1000; // 30 mins
  }

  function initialize(proc, name) {
    this.proc = proc;
    this.name = name;

    proc.stdout.on('data', #{ self.emit('stdout', $1.toString()) });
    proc.stderr.on('data', #{ self.emit('stderr', $1.toString()) });

    proc.on('exit', #{ self.emit('exit', $1) });
    setTimeout(#{ self.kill() }, TIMEOUT);
  }
  
  function pipe(socket) {
    self.on('stdout', #{ socket.emit('stdout', { data: $1.toString(), name: self.name }) });
    self.on('stderr', #{ socket.emit('stderr', { data: $1.toString(), name: self.name }) });
    self.on('exit', #{ socket.emit('exit', { code: $1, name: self.name }) });
  }

  function kill() {
    this.proc && this.proc.kill();
    this.proc = null;
    this.idDead = true;
  }
}
