// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

_exit(int status) native "Exit";

class _ProcessStartStatus {
  int _errorCode;  // Set to OS error code if process start failed.
  String _errorMessage;  // Set to OS error message if process start failed.
}


class _Process extends NativeFieldWrapperClass1 implements Process {
  static Future<ProcessResult> run(String path,
                                   List<String> arguments,
                                   [ProcessOptions options]) {
    return new _NonInteractiveProcess._start(path, arguments, options)._result;
  }

  _Process.start(String path,
                 List<String> arguments,
                 ProcessOptions options) {
    if (path is !String) {
      throw new ArgumentError("Path is not a String: $path");
    }
    _path = path;

    if (arguments is !List) {
      throw new ArgumentError("Arguments is not a List: $arguments");
    }
    int len = arguments.length;
    _arguments = new List<String>(len);
    for (int i = 0; i < len; i++) {
      var arg = arguments[i];
      if (arg is !String) {
        throw new ArgumentError("Non-string argument: $arg");
      }
      _arguments[i] = arguments[i];
      if (Platform.operatingSystem == 'windows') {
        _arguments[i] = _windowsArgumentEscape(_arguments[i]);
      }
    }

    if (options !== null && options.workingDirectory !== null) {
      _workingDirectory = options.workingDirectory;
      if (_workingDirectory is !String) {
        throw new ArgumentError(
            "WorkingDirectory is not a String: $_workingDirectory");
      }
    }

    if (options !== null && options.environment !== null) {
      var env = options.environment;
      if (env is !Map) {
        throw new ArgumentError("Environment is not a map: $env");
      }
      _environment = [];
      env.forEach((key, value) {
        if (key is !String || value is !String) {
          throw new ArgumentError(
              "Environment key or value is not a string: ($key, $value)");
        }
        _environment.add('$key=$value');
      });
    }

    _in = new _Socket._internalReadOnly();  // stdout coming from process.
    _out = new _Socket._internalWriteOnly();  // stdin going to process.
    _err = new _Socket._internalReadOnly();  // stderr coming from process.
    _exitHandler = new _Socket._internalReadOnly();
    _closed = false;
    _ended = false;
    _started = false;
    _onExit = null;
    // TODO(ager): Make the actual process starting really async instead of
    // simulating it with a timer.
    new Timer(0, (Timer ignore) => _start());
  }

  String _windowsArgumentEscape(String argument) {
    var result = argument;
    if (argument.contains('\t') || argument.contains(' ')) {
      // Produce something that the C runtime on Windows will parse
      // back as this string.

      // Replace any number of '\' followed by '"' with
      // twice as many '\' followed by '\"'.
      var backslash = '\\'.charCodeAt(0);
      var sb = new StringBuffer();
      var nextPos = 0;
      var quotePos = argument.indexOf('"', nextPos);
      while (quotePos != -1) {
        var numBackslash = 0;
        var pos = quotePos - 1;
        while (pos >= 0 && argument.charCodeAt(pos) == backslash) {
          numBackslash++;
          pos--;
        }
        sb.add(argument.substring(nextPos, quotePos - numBackslash));
        for (var i = 0; i < numBackslash; i++) {
          sb.add(r'\\');
        }
        sb.add(r'\"');
        nextPos = quotePos + 1;
        quotePos = argument.indexOf('"', nextPos);
      }
      sb.add(argument.substring(nextPos, argument.length));
      result = sb.toString();

      // Add '"' at the beginning and end and replace all '\' at
      // the end with two '\'.
      sb = new StringBuffer('"');
      sb.add(result);
      nextPos = argument.length - 1;
      while (argument.charCodeAt(nextPos) == backslash) {
        sb.add('\\');
        nextPos--;
      }
      sb.add('"');
      result = sb.toString();
    }

    return result;
  }

  int _intFromBytes(List<int> bytes, int offset) {
    return (bytes[offset] +
            (bytes[offset + 1] << 8) +
            (bytes[offset + 2] << 16) +
            (bytes[offset + 3] << 24));
  }

  void _start() {
    var status = new _ProcessStartStatus();
    bool success = _startNative(_path,
                                _arguments,
                                _workingDirectory,
                                _environment,
                                _in,
                                _out,
                                _err,
                                _exitHandler,
                                status);
    if (!success) {
      close();
      _reportError(new ProcessException(status._errorMessage,
                                        status._errorCode));
      return;
    }
    _started = true;

    _in._closed = false;
    _out._closed = false;
    _err._closed = false;
    _exitHandler._closed = false;

    // Make sure to activate socket handlers now that the file
    // descriptors have been set.
    _in._activateHandlers();
    _out._activateHandlers();
    _err._activateHandlers();

    // Setup an exit handler to handle internal cleanup and possible
    // callback when a process terminates.
    int exitDataRead = 0;
    final int EXIT_DATA_SIZE = 8;
    List<int> exitDataBuffer = new List<int>(EXIT_DATA_SIZE);
    _exitHandler.inputStream.onData = () {

      int exitCode(List<int> ints) {
        var code = _intFromBytes(ints, 0);
        var negative = _intFromBytes(ints, 4);
        assert(negative == 0 || negative == 1);
        return (negative == 0) ? code : -code;
      }

      void handleExit() {
        _ended = true;
        if (_onExit !== null) {
          _onExit(exitCode(exitDataBuffer));
        }
      }

      exitDataRead += _exitHandler.inputStream.readInto(
          exitDataBuffer, exitDataRead, EXIT_DATA_SIZE - exitDataRead);
      if (exitDataRead == EXIT_DATA_SIZE) handleExit();
    };

    if (_onStart !== null) {
      _onStart();
    }
  }

  bool _startNative(String path,
                    List<String> arguments,
                    String workingDirectory,
                    List<String> environment,
                    Socket input,
                    Socket output,
                    Socket error,
                    Socket exitHandler,
                    _ProcessStartStatus status) native "Process_Start";

  InputStream get stdout {
    if (_closed) {
      throw new ProcessException("Process closed");
    }
    return _in.inputStream;
  }

  InputStream get stderr {
    if (_closed) {
      throw new ProcessException("Process closed");
    }
    return _err.inputStream;
  }

  OutputStream get stdin {
    if (_closed) {
      throw new ProcessException("Process closed");
    }
    return _out.outputStream;
  }

  void kill([ProcessSignal signal = ProcessSignal.SIGTERM]) {
    if (signal is! ProcessSignal) {
      throw new ArgumentError(
          "Argument 'signal' must be a ProcessSignal");
    }
    if (!_started) {
      var e = new ProcessException("Cannot kill process that is not started");
      _reportError(e);
      return;
    }
    if (_ended) {
      return;
    }
    if (_kill(this, signal._signalNumber)) {
      return;
    }
    _reportError(new ProcessException("Could not kill process"));
    return;
  }

  bool _kill(Process p, int signal) native "Process_Kill";

  void close() {
    if (_closed) {
      throw new ProcessException("Process closed");
    }
    _in.close();
    _out.close();
    _err.close();
    _exitHandler.close();
    _closed = true;
  }

  void set onExit(void callback(int exitCode)) {
    if (_closed) {
      throw new ProcessException("Process closed");
    }
    if (_ended) {
      throw new ProcessException("Process killed");
    }
    _onExit = callback;
  }

  void set onError(void callback(e)) {
    _onError = callback;
  }

  void set onStart(void callback()) {
    _onStart = callback;
  }

  void _reportError(e) {
    if (_onError != null) {
      _onError(e);
    } else {
      throw e;
    }
  }

  String _path;
  List<String> _arguments;
  String _workingDirectory;
  List<String> _environment;
  // Private methods of _Socket are used by _in, _out, and _err.
  _Socket _in;
  _Socket _out;
  _Socket _err;
  Socket _exitHandler;
  bool _closed;
  bool _ended;
  bool _started;
  Function _onExit;
  Function _onError;
  Function _onStart;
}


// _NonInteractiveProcess is a wrapper around an interactive process
// that buffers output so it can be delivered when the process exits.
// _NonInteractiveProcess is used to implement the Process.run
// method.
class _NonInteractiveProcess {
  _NonInteractiveProcess._start(String path,
                                List<String> arguments,
                                ProcessOptions options) {
    _completer = new Completer<ProcessResult>();
    // Extract output encoding options and verify arguments.
    var stdoutEncoding = Encoding.UTF_8;
    var stderrEncoding = Encoding.UTF_8;
    if (options !== null) {
      if (options.stdoutEncoding !== null) {
        stdoutEncoding = options.stdoutEncoding;
        if (stdoutEncoding is !Encoding) {
          throw new ArgumentError(
              'stdoutEncoding option is not an encoding: $stdoutEncoding');
        }
      }
      if (options.stderrEncoding !== null) {
        stderrEncoding = options.stderrEncoding;
        if (stderrEncoding is !Encoding) {
          throw new ArgumentError(
              'stderrEncoding option is not an encoding: $stderrEncoding');
        }
      }
    }

    // Start the underlying process.
    _process = new _Process.start(path, arguments, options);

    // Make sure stdin is closed.
    _process.onStart = _process.stdin.close;

    // Setup process error handling.
    _process.onError = (e) => _completer.completeException(e);

    // Setup process exit handling.
    _process.onExit = (exitCode) {
      _exitCode = exitCode;
      _checkDone();
    };

    // Setup stdout handling.
    _stdoutBuffer = new StringBuffer();
    var stdoutStream = new StringInputStream(_process.stdout, stdoutEncoding);
    stdoutStream.onData = () {
      var data = stdoutStream.read();
      if (data != null) _stdoutBuffer.add(data);
    };
    stdoutStream.onClosed = () {
      _stdoutClosed = true;
      _checkDone();
    };

    // Setup stderr handling.
    _stderrBuffer = new StringBuffer();
    var stderrStream = new StringInputStream(_process.stderr, stderrEncoding);
    stderrStream.onData = () {
      var data = stderrStream.read();
      if (data != null) _stderrBuffer.add(data);
    };
    stderrStream.onClosed = () {
      _stderrClosed = true;
      _checkDone();
    };
  }

  void _checkDone() {
    if (_exitCode != null && _stderrClosed && _stdoutClosed) {
      _completer.complete(new _ProcessResult(_exitCode,
                                             _stdoutBuffer.toString(),
                                             _stderrBuffer.toString()));
    }
  }

  Future<ProcessResult> get _result => _completer.future;

  Completer<ProcessResult> _completer;
  Process _process;
  StringBuffer _stdoutBuffer;
  StringBuffer _stderrBuffer;
  int _exitCode;
  bool _stdoutClosed = false;
  bool _stderrClosed = false;
}


class _ProcessResult implements ProcessResult {
  const _ProcessResult(int this.exitCode,
                       String this.stdout,
                       String this.stderr);

  final int exitCode;
  final String stdout;
  final String stderr;
}
