// 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.

class _FileInputStream extends _BaseDataInputStream implements InputStream {
  _FileInputStream(String name)
      : _data = const [],
        _position = 0,
        _filePosition = 0 {
    var file = new File(name);
    var future = file.open(FileMode.READ);
    future.handleException((e) {
      _reportError(e);
      return true;
    });
    future.then(_setupOpenedFile);
  }

  _FileInputStream.fromStdio(int fd)
      : _data = const [],
        _position = 0,
        _filePosition = 0 {
    assert(fd == 0);
    _setupOpenedFile(_File._openStdioSync(fd));
  }

  void _setupOpenedFile(RandomAccessFile openedFile) {
    _openedFile = openedFile;
    if (_streamMarkedClosed) {
      // This input stream has already been closed.
      _fileLength = 0;
      _closeFile();
      return;
    }
    var futureOpen = _openedFile.length();
    futureOpen.then((len) {
      _fileLength = len;
      _fillBuffer();
    });
    futureOpen.handleException((e) {
      _reportError(e);
      return true;
    });
  }

  void _closeFile() {
    if (_openedFile == null) {
      _streamMarkedClosed = true;
      return;
    }
    if (available() == 0) _cancelScheduledDataCallback();
    if (!_openedFile.closed) {
      _openedFile.close().then((ignore) {
        _streamMarkedClosed = true;
        _checkScheduleCallbacks();
      });
    }
  }

  void _fillBuffer() {
    Expect.equals(_position, _data.length);
    if (_openedFile == null) return;  // Called before the file is opened.
    int size = min(_bufferLength, _fileLength - _filePosition);
    if (size == 0) {
      _closeFile();
      return;
    }
    // If there is currently a _fillBuffer call waiting on readList,
    // let it fill the buffer instead of us.
    if (_activeFillBufferCall) return;
    _activeFillBufferCall = true;
    if (_data.length != size) {
      _data = new Uint8List(size);
      // Maintain the invariant signalling that the buffer is empty.
      _position = _data.length;
    }
    var future = _openedFile.readList(_data, 0, _data.length);
    future.then((read) {
      _filePosition += read;
      if (read != _data.length) {
        _data = _data.getRange(0, read);
      }
      _position = 0;
      _activeFillBufferCall = false;

      if (_fileLength == _filePosition) {
        _closeFile();
      }
      _checkScheduleCallbacks();
    });
    future.handleException((e) {
      _activeFillBufferCall = false;
      _reportError(e);
      return true;
    });
  }

  int available() {
    return closed ? 0 : _data.length - _position;
  }

  void pipe(OutputStream output, {bool close: true}) {
    _pipe(this, output, close: close);
  }

  void _finishRead() {
    if (_position == _data.length && !_streamMarkedClosed) {
      _fillBuffer();
    } else {
      _checkScheduleCallbacks();
    }
  }

  List<int> _read(int bytesToRead) {
    List<int> result;
    if (_position == 0 && bytesToRead == _data.length) {
      result = _data;
      _data = const [];
    } else {
      result = new Uint8List(bytesToRead);
      result.setRange(0, bytesToRead, _data, _position);
      _position += bytesToRead;
    }
    _finishRead();
    return result;
  }

  int _readInto(List<int> buffer, int offset, int len) {
    buffer.setRange(offset, len, _data, _position);
    _position += len;
    _finishRead();
    return len;
  }

  void _close() {
    _data = const [];
    _position = 0;
    _filePosition = 0;
    _fileLength = 0;
    _closeFile();
  }

  static const int _bufferLength = 64 * 1024;

  RandomAccessFile _openedFile;
  List<int> _data;
  int _position;
  int _filePosition;
  int _fileLength;
  bool _activeFillBufferCall = false;
}


class _PendingOperation {
  const _PendingOperation(this._id);
  static const _PendingOperation CLOSE = const _PendingOperation(0);
  static const _PendingOperation FLUSH = const _PendingOperation(1);
  final int _id;
}


class _FileOutputStream extends _BaseOutputStream implements OutputStream {
  _FileOutputStream(String name, FileMode mode) {
    _pendingOperations = new List();
    var f = new File(name);
    var openFuture = f.open(mode);
    openFuture.then((openedFile) {
      _file = openedFile;
      _processPendingOperations();
    });
    openFuture.handleException((e) {
      _reportError(e);
      return true;
    });
  }

  _FileOutputStream.fromStdio(int fd) {
    assert(1 <= fd && fd <= 2);
    _file = _File._openStdioSync(fd);
  }

  bool write(List<int> buffer, [bool copyBuffer = false]) {
    var data = buffer;
    if (copyBuffer) {
      var length = buffer.length;
      data = new Uint8List(length);
      data.setRange(0, length, buffer, 0);
    }
    if (_file == null) {
      _pendingOperations.add(data);
    } else {
      _write(data, 0, data.length);
    }
    return false;
  }

  bool writeFrom(List<int> buffer, [int offset = 0, int len]) {
    // A copy is required by the interface.
    var length = buffer.length - offset;
    if (len != null) {
      if (len > length) throw new RangeError.value(len);
      length = len;
    }
    var copy = new Uint8List(length);
    copy.setRange(0, length, buffer, offset);
    return write(copy);
  }


  void flush() {
    if (_file == null) {
      _pendingOperations.add(_PendingOperation.FLUSH);
    } else {
      _file.flush().then((ignored) => null);
    }
  }


  void close() {
    _streamMarkedClosed = true;
    if (_file == null) {
      _pendingOperations.add(_PendingOperation.CLOSE);
    } else if (!_closeCallbackScheduled) {
      _file.close().then((ignore) {
        if (_onClosed != null) _onClosed();
      });
      _closeCallbackScheduled = true;
    }
  }

  void set onNoPendingWrites(void callback()) {
    _onNoPendingWrites = callback;
    if ((_pendingOperations == null || _pendingOperations.length == 0) &&
        outstandingWrites == 0 &&
        !_streamMarkedClosed &&
        _onNoPendingWrites != null) {
      new Timer(0, (t) {
        if (_onNoPendingWrites != null) {
          _onNoPendingWrites();
        }
      });
    }
  }

  void set onClosed(void callback()) {
    _onClosed = callback;
  }

  void _processPendingOperations() {
    _pendingOperations.forEach((buffer) {
      if (buffer is _PendingOperation) {
        if (identical(buffer, _PendingOperation.CLOSE)) {
          close();
        } else {
          assert(identical(buffer, _PendingOperation.FLUSH));
          flush();
        }
      } else {
        write(buffer);
      }
    });
    _pendingOperations = null;
  }

  void _write(List<int> buffer, int offset, int len) {
    outstandingWrites++;
    var writeListFuture = _file.writeList(buffer, offset, len);
    writeListFuture.then((ignore) {
        outstandingWrites--;
        if (outstandingWrites == 0 &&
            !_streamMarkedClosed &&
            _onNoPendingWrites != null) {
          _onNoPendingWrites();
        }
    });
    writeListFuture.handleException((e) {
      outstandingWrites--;
      _reportError(e);
      return true;
    });
  }

  bool get closed => _streamMarkedClosed;

  RandomAccessFile _file;

  // When this is set to true the stream is marked closed. When a
  // stream is marked closed no more data can be written.
  bool _streamMarkedClosed = false;

  // When this is set to true, the close callback has been scheduled and the
  // stream will be fully closed once it's called.
  bool _closeCallbackScheduled = false;

  // Number of writes that have not yet completed.
  int outstandingWrites = 0;

  // List of pending writes that were issued before the underlying
  // file was successfully opened.
  List _pendingOperations;

  Function _onNoPendingWrites;
  Function _onClosed;
}

const int _EXISTS_REQUEST = 0;
const int _CREATE_REQUEST = 1;
const int _DELETE_REQUEST = 2;
const int _OPEN_REQUEST = 3;
const int _FULL_PATH_REQUEST = 4;
const int _DIRECTORY_REQUEST = 5;
const int _CLOSE_REQUEST = 6;
const int _POSITION_REQUEST = 7;
const int _SET_POSITION_REQUEST = 8;
const int _TRUNCATE_REQUEST = 9;
const int _LENGTH_REQUEST = 10;
const int _LENGTH_FROM_NAME_REQUEST = 11;
const int _LAST_MODIFIED_REQUEST = 12;
const int _FLUSH_REQUEST = 13;
const int _READ_BYTE_REQUEST = 14;
const int _WRITE_BYTE_REQUEST = 15;
const int _READ_LIST_REQUEST = 16;
const int _WRITE_LIST_REQUEST = 17;

// Base class for _File and _RandomAccessFile with shared functions.
class _FileBase {
  bool _isErrorResponse(response) {
    return response is List && response[0] != _SUCCESS_RESPONSE;
  }

  _exceptionFromResponse(response, String message) {
    assert(_isErrorResponse(response));
    switch (response[_ERROR_RESPONSE_ERROR_TYPE]) {
      case _ILLEGAL_ARGUMENT_RESPONSE:
        return new ArgumentError();
      case _OSERROR_RESPONSE:
        var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE],
                              response[_OSERROR_RESPONSE_ERROR_CODE]);
        return new FileIOException(message, err);
      case _FILE_CLOSED_RESPONSE:
        return new FileIOException("File closed");
      default:
        return new Exception("Unknown error");
    }
  }
}

// TODO(ager): The only reason for this class is that the patching
// mechanism doesn't seem to like patching a private top level
// function.
class _FileUtils {
  external static SendPort _newServicePort();
}

// Class for encapsulating the native implementation of files.
class _File extends _FileBase implements File {
  // Constructor for file.
  _File(String this._name) {
    if (_name is! String) {
      throw new ArgumentError('${NoSuchMethodError.safeToString(_name)} '
                              'is not a String');
    }
  }

  // Constructor from Path for file.
  _File.fromPath(Path path) : this(path.toNativePath());

  Future<bool> exists() {
    _ensureFileService();
    List request = new List(2);
    request[0] = _EXISTS_REQUEST;
    request[1] = _name;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response, "Cannot open file '$_name'");
      }
      return response;
    });
  }

  external static _exists(String name);

  bool existsSync() {
    var result = _exists(_name);
    throwIfError(result, "Cannot check existence of file '$_name'");
    return result;
  }

  Future<File> create() {
    _ensureFileService();
    List request = new List(2);
    request[0] = _CREATE_REQUEST;
    request[1] = _name;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response, "Cannot create file '$_name'");
      }
      return this;
    });
  }

  external static _create(String name);

  void createSync() {
    var result = _create(_name);
    throwIfError(result, "Cannot create file '$_name'");
  }

  Future<File> delete() {
    _ensureFileService();
    List request = new List(2);
    request[0] = _DELETE_REQUEST;
    request[1] = _name;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response, "Cannot delete file '$_name'");
      }
      return this;
    });
  }

  external static _delete(String name);

  void deleteSync() {
    var result = _delete(_name);
    throwIfError(result, "Cannot delete file '$_name'");
  }

  Future<Directory> directory() {
    _ensureFileService();
    List request = new List(2);
    request[0] = _DIRECTORY_REQUEST;
    request[1] = _name;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "Cannot retrieve directory for "
                                     "file '$_name'");
      }
      return new Directory(response);
    });
  }

  external static _directory(String name);

  Directory directorySync() {
    var result = _directory(name);
    throwIfError(result, "Cannot retrieve directory for file '$_name'");
    return new Directory(result);
  }

  Future<RandomAccessFile> open([FileMode mode = FileMode.READ]) {
    _ensureFileService();
    Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
    if (mode != FileMode.READ &&
        mode != FileMode.WRITE &&
        mode != FileMode.APPEND) {
      new Timer(0, (t) {
        completer.completeException(new ArgumentError());
      });
      return completer.future;
    }
    List request = new List(3);
    request[0] = _OPEN_REQUEST;
    request[1] = _name;
    request[2] = mode._mode;  // Direct int value for serialization.
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response, "Cannot open file '$_name'");
      }
      return new _RandomAccessFile(response, _name);
    });
  }

  Future<int> length() {
    _ensureFileService();
    List request = new List(2);
    request[0] = _LENGTH_FROM_NAME_REQUEST;
    request[1] = _name;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "Cannot retrieve length of "
                                     "file '$_name'");
      }
      return response;
    });
  }


  external static _lengthFromName(String name);

  int lengthSync() {
    var result = _lengthFromName(_name);
    throwIfError(result, "Cannot retrieve length of file '$_name'");
    return result;
  }

  Future<Date> lastModified() {
    _ensureFileService();
    List request = new List(2);
    request[0] = _LAST_MODIFIED_REQUEST;
    request[1] = _name;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "Cannot retrieve modification time "
                                     "for file '$_name'");
      }
      return new Date.fromMillisecondsSinceEpoch(response);
    });
  }

  external static _lastModified(String name);

  Date lastModifiedSync() {
    var ms = _lastModified(name);
    throwIfError(ms, "Cannot retrieve modification time for file '$_name'");
    return new Date.fromMillisecondsSinceEpoch(ms);
  }

  external static _open(String name, int mode);

  RandomAccessFile openSync([FileMode mode = FileMode.READ]) {
    if (mode != FileMode.READ &&
        mode != FileMode.WRITE &&
        mode != FileMode.APPEND) {
      throw new FileIOException("Unknown file mode. Use FileMode.READ, "
                                "FileMode.WRITE or FileMode.APPEND.");
    }
    var id = _open(_name, mode._mode);
    throwIfError(id, "Cannot open file '$_name'");
    return new _RandomAccessFile(id, _name);
  }

  external static int _openStdio(int fd);

  static RandomAccessFile _openStdioSync(int fd) {
    var id = _openStdio(fd);
    if (id == 0) {
      throw new FileIOException("Cannot open stdio file for: $fd");
    }
    return new _RandomAccessFile(id, "");
  }

  Future<String> fullPath() {
    _ensureFileService();
    List request = new List(2);
    request[0] = _FULL_PATH_REQUEST;
    request[1] = _name;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "Cannot retrieve full path"
                                     " for '$_name'");
      }
      return response;
    });
  }

  external static _fullPath(String name);

  String fullPathSync() {
    var result = _fullPath(_name);
    throwIfError(result, "Cannot retrieve full path for file '$_name'");
    return result;
  }

  InputStream openInputStream() {
    return new _FileInputStream(_name);
  }

  OutputStream openOutputStream([FileMode mode = FileMode.WRITE]) {
    if (mode != FileMode.WRITE &&
        mode != FileMode.APPEND) {
      throw new FileIOException(
          "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND");
    }
    return new _FileOutputStream(_name, mode);
  }

  Future<List<int>> readAsBytes() {
    _ensureFileService();
    Completer<List<int>> completer = new Completer<List<int>>();
    var chunks = new _BufferList();
    var stream = openInputStream();
    stream.onClosed = () {
      var result = chunks.readBytes(chunks.length);
      if (result == null) result = <int>[];
      completer.complete(result);
    };
    stream.onData = () {
      var chunk = stream.read();
      chunks.add(chunk);
    };
    stream.onError = completer.completeException;
    return completer.future;
  }

  List<int> readAsBytesSync() {
    var opened = openSync();
    var length = opened.lengthSync();
    var result = new Uint8List(length);
    var read = opened.readListSync(result, 0, length);
    if (read != length) {
      throw new FileIOException("Failed to read file");
    }
    opened.closeSync();
    return result;
  }

  Future<String> readAsText([Encoding encoding = Encoding.UTF_8]) {
    _ensureFileService();
    return readAsBytes().transform((bytes) {
      if (bytes.length == 0) return "";
      var decoder = _StringDecoders.decoder(encoding);
      decoder.write(bytes);
      return decoder.decoded();
    });
  }

  String readAsTextSync([Encoding encoding = Encoding.UTF_8]) {
    var decoder = _StringDecoders.decoder(encoding);
    List<int> bytes = readAsBytesSync();
    if (bytes.length == 0) return "";
    decoder.write(bytes);
    return decoder.decoded();
  }

  List<String> _getDecodedLines(_StringDecoder decoder) {
    List<String> result = [];
    var line = decoder.decodedLine;
    while (line != null) {
      result.add(line);
      line = decoder.decodedLine;
    }
    // If there is more data with no terminating line break we treat
    // it as the last line.
    var data = decoder.decoded();
    if (data != null) {
      result.add(data);
    }
    return result;
  }

  Future<List<String>> readAsLines([Encoding encoding = Encoding.UTF_8]) {
    _ensureFileService();
    Completer<List<String>> completer = new Completer<List<String>>();
    return readAsBytes().transform((bytes) {
      var decoder = _StringDecoders.decoder(encoding);
      decoder.write(bytes);
      return _getDecodedLines(decoder);
    });
  }

  List<String> readAsLinesSync([Encoding encoding = Encoding.UTF_8]) {
    var decoder = _StringDecoders.decoder(encoding);
    List<int> bytes = readAsBytesSync();
    decoder.write(bytes);
    return _getDecodedLines(decoder);
  }

  String get name => _name;

  void _ensureFileService() {
    if (_fileService == null) {
      _fileService = _FileUtils._newServicePort();
    }
  }

  static throwIfError(Object result, String msg) {
    if (result is OSError) {
      throw new FileIOException(msg, result);
    }
  }

  final String _name;

  SendPort _fileService;
}


class _RandomAccessFile extends _FileBase implements RandomAccessFile {
  _RandomAccessFile(int this._id, String this._name);

  Future<RandomAccessFile> close() {
    Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
    if (closed) return _completeWithClosedException(completer);
    _ensureFileService();
    List request = new List(2);
    request[0] = _CLOSE_REQUEST;
    request[1] = _id;
    // Set the id_ to 0 (NULL) to ensure the no more async requests
    // can be issued for this file.
    _id = 0;
    return _fileService.call(request).transform((result) {
      if (result != -1) {
        _id = result;
        return this;
      } else {
        throw new FileIOException("Cannot close file '$_name'");
      }
    });
  }

  external static int _close(int id);

  void closeSync() {
    _checkNotClosed();
    var id = _close(_id);
    if (id == -1) {
      throw new FileIOException("Cannot close file '$_name'");
    }
    _id = id;
  }

  Future<int> readByte() {
    _ensureFileService();
    Completer<int> completer = new Completer<int>();
    if (closed) return _completeWithClosedException(completer);
    List request = new List(2);
    request[0] = _READ_BYTE_REQUEST;
    request[1] = _id;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "readByte failed for file '$_name'");
      }
      return response;
    });
  }

  external static _readByte(int id);

  int readByteSync() {
    _checkNotClosed();
    var result = _readByte(_id);
    if (result is OSError) {
      throw new FileIOException("readByte failed for file '$_name'", result);
    }
    return result;
  }

  Future<int> readList(List<int> buffer, int offset, int bytes) {
    _ensureFileService();
    Completer<int> completer = new Completer<int>();
    if (buffer is !List || offset is !int || bytes is !int) {
      // Complete asynchronously so the user has a chance to setup
      // handlers without getting exceptions when registering the
      // then handler.
      new Timer(0, (t) {
        completer.completeException(new FileIOException(
            "Invalid arguments to readList for file '$_name'"));
      });
      return completer.future;
    };
    if (closed) return _completeWithClosedException(completer);
    List request = new List(3);
    request[0] = _READ_LIST_REQUEST;
    request[1] = _id;
    request[2] = bytes;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "readList failed for file '$_name'");
      }
      var read = response[1];
      var data = response[2];
      buffer.setRange(offset, read, data);
      return read;
    });
  }

  static void _checkReadWriteListArguments(int length, int offset, int bytes) {
    if (offset < 0) throw new RangeError.value(offset);
    if (bytes < 0) throw new RangeError.value(bytes);
    if ((offset + bytes) > length) {
      throw new RangeError.value(offset + bytes);
    }
  }

  external static _readList(int id, List<int> buffer, int offset, int bytes);

  int readListSync(List<int> buffer, int offset, int bytes) {
    _checkNotClosed();
    if (buffer is !List || offset is !int || bytes is !int) {
      throw new FileIOException(
          "Invalid arguments to readList for file '$_name'");
    }
    if (bytes == 0) return 0;
    _checkReadWriteListArguments(buffer.length, offset, bytes);
    var result = _readList(_id, buffer, offset, bytes);
    if (result is OSError) {
      throw new FileIOException("readList failed for file '$_name'",
                                result);
    }
    return result;
  }

  Future<RandomAccessFile> writeByte(int value) {
    _ensureFileService();
    Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
    if (value is !int) {
      // Complete asynchronously so the user has a chance to setup
      // handlers without getting exceptions when registering the
      // then handler.
      new Timer(0, (t) {
          completer.completeException(new FileIOException(
              "Invalid argument to writeByte for file '$_name'"));
      });
      return completer.future;
    }
    if (closed) return _completeWithClosedException(completer);
    List request = new List(3);
    request[0] = _WRITE_BYTE_REQUEST;
    request[1] = _id;
    request[2] = value;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "writeByte failed for file '$_name'");
      }
      return this;
    });
  }

  external static _writeByte(int id, int value);

  int writeByteSync(int value) {
    _checkNotClosed();
    if (value is !int) {
      throw new FileIOException(
          "Invalid argument to writeByte for file '$_name'");
    }
    var result = _writeByte(_id, value);
    if (result is OSError) {
      throw new FileIOException("writeByte failed for file '$_name'",
                                result);
    }
    return result;
  }

  Future<RandomAccessFile> writeList(List<int> buffer, int offset, int bytes) {
    _ensureFileService();
    Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
    if (buffer is !List || offset is !int || bytes is !int) {
      // Complete asynchronously so the user has a chance to setup
      // handlers without getting exceptions when registering the
      // then handler.
      new Timer(0, (t) {
          completer.completeException(new FileIOException(
          "Invalid arguments to writeList for file '$_name'"));
      });
      return completer.future;
    }
    if (closed) return _completeWithClosedException(completer);

    _BufferAndOffset result;
    try {
      result = _ensureFastAndSerializableBuffer(buffer, offset, bytes);
    } catch (e) {
      // Complete asynchronously so the user has a chance to setup
      // handlers without getting exceptions when registering the
      // then handler.
      new Timer(0, (t) => completer.completeException(e));
      return completer.future;
    }

    List request = new List(5);
    request[0] = _WRITE_LIST_REQUEST;
    request[1] = _id;
    request[2] = result.buffer;
    request[3] = result.offset;
    request[4] = bytes;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "writeList failed for file '$_name'");
      }
      return this;
    });
  }

  external static _writeList(int id, List<int> buffer, int offset, int bytes);

  int writeListSync(List<int> buffer, int offset, int bytes) {
    _checkNotClosed();
    if (buffer is !List || offset is !int || bytes is !int) {
      throw new FileIOException(
          "Invalid arguments to writeList for file '$_name'");
    }
    if (bytes == 0) return 0;
    _checkReadWriteListArguments(buffer.length, offset, bytes);
    _BufferAndOffset bufferAndOffset =
        _ensureFastAndSerializableBuffer(buffer, offset, bytes);
    var result =
      _writeList(_id, bufferAndOffset.buffer, bufferAndOffset.offset, bytes);
    if (result is OSError) {
      throw new FileIOException("writeList failed for file '$_name'", result);
    }
    return result;
  }

  Future<RandomAccessFile> writeString(String string,
                                       [Encoding encoding = Encoding.UTF_8]) {
    if (encoding is! Encoding) {
      var completer = new Completer();
      new Timer(0, (t) {
        completer.completeException(new FileIOException(
            "Invalid encoding in writeString: $encoding"));
      });
      return completer.future;
    }
    var data = _StringEncoders.encoder(encoding).encodeString(string);
    return writeList(data, 0, data.length);
  }

  int writeStringSync(String string, [Encoding encoding = Encoding.UTF_8]) {
    if (encoding is! Encoding) {
      throw new FileIOException(
          "Invalid encoding in writeStringSync: $encoding");
    }
    var data = _StringEncoders.encoder(encoding).encodeString(string);
    return writeListSync(data, 0, data.length);
  }

  Future<int> position() {
    _ensureFileService();
    Completer<int> completer = new Completer<int>();
    if (closed) return _completeWithClosedException(completer);
    List request = new List(2);
    request[0] = _POSITION_REQUEST;
    request[1] = _id;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "position failed for file '$_name'");
      }
      return response;
    });
  }

  external static _position(int id);

  int positionSync() {
    _checkNotClosed();
    var result = _position(_id);
    if (result is OSError) {
      throw new FileIOException("position failed for file '$_name'", result);
    }
    return result;
  }

  Future<RandomAccessFile> setPosition(int position) {
    _ensureFileService();
    Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
    if (closed) return _completeWithClosedException(completer);
    List request = new List(3);
    request[0] = _SET_POSITION_REQUEST;
    request[1] = _id;
    request[2] = position;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "setPosition failed for file '$_name'");
      }
      return this;
    });
  }

  external static _setPosition(int id, int position);

  void setPositionSync(int position) {
    _checkNotClosed();
    var result = _setPosition(_id, position);
    if (result is OSError) {
      throw new FileIOException("setPosition failed for file '$_name'", result);
    }
  }

  Future<RandomAccessFile> truncate(int length) {
    _ensureFileService();
    Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
    if (closed) return _completeWithClosedException(completer);
    List request = new List(3);
    request[0] = _TRUNCATE_REQUEST;
    request[1] = _id;
    request[2] = length;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "truncate failed for file '$_name'");
      }
      return this;
    });
  }

  external static _truncate(int id, int length);

  void truncateSync(int length) {
    _checkNotClosed();
    var result = _truncate(_id, length);
    if (result is OSError) {
      throw new FileIOException("truncate failed for file '$_name'", result);
    }
  }

  Future<int> length() {
    _ensureFileService();
    Completer<int> completer = new Completer<int>();
    if (closed) return _completeWithClosedException(completer);
    List request = new List(2);
    request[0] = _LENGTH_REQUEST;
    request[1] = _id;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "length failed for file '$_name'");
      }
      return response;
    });
  }

  external static _length(int id);

  int lengthSync() {
    _checkNotClosed();
    var result = _length(_id);
    if (result is OSError) {
      throw new FileIOException("length failed for file '$_name'", result);
    }
    return result;
  }

  Future<RandomAccessFile> flush() {
    _ensureFileService();
    Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
    if (closed) return _completeWithClosedException(completer);
    List request = new List(2);
    request[0] = _FLUSH_REQUEST;
    request[1] = _id;
    return _fileService.call(request).transform((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "flush failed for file '$_name'");
      }
      return this;
    });
  }

  external static _flush(int id);

  void flushSync() {
    _checkNotClosed();
    var result = _flush(_id);
    if (result is OSError) {
      throw new FileIOException("flush failed for file '$_name'", result);
    }
  }

  String get name => _name;

  void _ensureFileService() {
    if (_fileService == null) {
      _fileService = _FileUtils._newServicePort();
    }
  }

  bool get closed => _id == 0;

  void _checkNotClosed() {
    if (closed) {
      throw new FileIOException("File closed '$_name'");
    }
  }

  Future _completeWithClosedException(Completer completer) {
    new Timer(0, (t) {
      completer.completeException(
          new FileIOException("File closed '$_name'"));
    });
    return completer.future;
  }

  final String _name;
  int _id;

  SendPort _fileService;
}
