// Copyright (c) 2013, 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.

part of dart.io;

// Read the file in blocks of size 64k.
const int _BLOCK_SIZE = 64 * 1024;


class _FileStream extends Stream<List<int>> {
  // Stream controller.
  StreamController<List<int>> _controller;

  // Information about the underlying file.
  String _path;
  RandomAccessFile _openedFile;
  int _position;
  int _end;

  // Has the stream been paused or unsubscribed?
  bool _paused = false;
  bool _unsubscribed = false;

  // Is there a read currently in progress?
  bool _readInProgress = false;

  // Block read but not yet send because stream is paused.
  List<int> _currentBlock;

  _FileStream(String this._path, this._position, this._end) {
    _setupController();
  }

  _FileStream.forStdin() : _position = 0 {
    _setupController();
  }

  StreamSubscription<List<int>> listen(void onData(List<int> event),
                                       {void onError(error),
                                        void onDone(),
                                        bool cancelOnError}) {
    return _controller.stream.listen(onData,
                                     onError: onError,
                                     onDone: onDone,
                                     cancelOnError: cancelOnError);
  }

  void _setupController() {
    _controller = new StreamController<List<int>>(sync: true,
        onListen: _start,
        onPause: () => _paused = true,
        onResume: _resume,
        onCancel: () {
          _unsubscribed = true;
          _closeFile();
        });
  }

  Future _closeFile() {
    Future closeFuture;
    if (_openedFile != null) {
      Future closeFuture = _openedFile.close();
      _openedFile = null;
      return closeFuture;
    } else {
      return new Future.value();
    }
  }

  void _readBlock() {
    // Don't start a new read if one is already in progress.
    if (_readInProgress) return;
    _readInProgress = true;
    int readBytes = _BLOCK_SIZE;
    if (_end != null) {
      readBytes = min(readBytes, _end - _position);
      if (readBytes < 0) {
        if (!_unsubscribed) {
          _controller.addError(new RangeError("Bad end position: $_end"));
          _closeFile().then((_) { _controller.close(); });
          _unsubscribed = true;
        }
        return;
      }
    }
    _openedFile.read(readBytes)
      .then((block) {
        _readInProgress = false;
        if (block.length == 0) {
          if (!_unsubscribed) {
            _closeFile().then((_) { _controller.close(); });
            _unsubscribed = true;
          }
          return;
        }
        _position += block.length;
        if (_paused) {
          _currentBlock = block;
        } else {
          _controller.add(block);
          _readBlock();
        }
      })
      .catchError((e) {
        if (!_unsubscribed) {
          _controller.addError(e);
          _closeFile().then((_) { _controller.close(); });
          _unsubscribed = true;
        }
      });
  }

  void _start() {
    if (_position == null) {
      _position = 0;
    } else if (_position < 0) {
      _controller.addError(new RangeError("Bad start position: $_position"));
      _controller.close();
      return;
    }
    Future<RandomAccessFile> openFuture;
    if (_path != null) {
      openFuture = new File(_path).open(mode: FileMode.READ);
    } else {
      openFuture = new Future.value(_File._openStdioSync(0));
    }
    openFuture
      .then((RandomAccessFile opened) {
        _openedFile = opened;
        if (_position > 0) {
          return opened.setPosition(_position);
        }
      })
      .then((_) => _readBlock())
      .catchError((e) {
        _controller.addError(e);
        _controller.close();
      });
  }

  void _resume() {
    _paused = false;
    if (_currentBlock != null) {
      _controller.add(_currentBlock);
      _currentBlock = null;
    }
    // Resume reading unless we are already done.
    if (_openedFile != null) _readBlock();
  }
}

class _FileStreamConsumer extends StreamConsumer<List<int>> {
  File _file;
  Future<RandomAccessFile> _openFuture;
  StreamSubscription _subscription;

  _FileStreamConsumer(File this._file, FileMode mode) {
    _openFuture = _file.open(mode: mode);
  }

  _FileStreamConsumer.fromStdio(int fd) {
    assert(1 <= fd && fd <= 2);
    _openFuture = new Future.value(_File._openStdioSync(fd));
  }

  Future<File> addStream(Stream<List<int>> stream) {
    Completer<File> completer = new Completer<File>();
    _openFuture
      .then((openedFile) {
        _subscription = stream.listen(
          (d) {
            _subscription.pause();
            openedFile.writeFrom(d, 0, d.length)
              .then((_) => _subscription.resume())
              .catchError((e) {
                openedFile.close();
                completer.completeError(e);
              });
          },
          onDone: () {
            completer.complete(_file);
          },
          onError: (e) {
            openedFile.close();
            completer.completeError(e);
          },
          cancelOnError: true);
      })
      .catchError((e) {
        completer.completeError(e);
      });
    return completer.future;
  }

  Future<File> close() {
    return _openFuture.then((openedFile) => openedFile.close());
  }
}


const int _EXISTS_REQUEST = 0;
const int _CREATE_REQUEST = 1;
const int _DELETE_REQUEST = 2;
const int _RENAME_REQUEST = 3;
const int _OPEN_REQUEST = 4;
const int _FULL_PATH_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_PATH_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_REQUEST = 16;
const int _READ_LIST_REQUEST = 17;
const int _WRITE_LIST_REQUEST = 18;
const int _CREATE_LINK_REQUEST = 19;
const int _DELETE_LINK_REQUEST = 20;
const int _RENAME_LINK_REQUEST = 21;
const int _LINK_TARGET_REQUEST = 22;
const int _TYPE_REQUEST = 23;
const int _IDENTICAL_REQUEST = 24;
const int _STAT_REQUEST = 25;

// 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 implements File {
  // Constructor for file.
  _File(String this._path) {
    if (_path is! String) {
      throw new ArgumentError('${Error.safeToString(_path)} '
                              '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] = _path;
    return _fileService.call(request).then((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "Cannot check existence of file '$_path'");
      }
      return response;
    });
  }

  external static _exists(String path);

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

  Future<FileStat> stat() => FileStat.stat(path);

  FileStat statSync() => FileStat.statSync(path);

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

  external static _create(String path);

  external static _createLink(String path, String target);

  external static _linkTarget(String path);

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

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

  external static _delete(String path);

  external static _deleteLink(String path);

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

  Future<File> rename(String newPath) {
    _ensureFileService();
    List request = new List(3);
    request[0] = _RENAME_REQUEST;
    request[1] = _path;
    request[2] = newPath;
    return _fileService.call(request).then((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(
            response, "Cannot rename file '$_path' to '$newPath'");
      }
      return new File(newPath);
    });
  }

  external static _rename(String oldPath, String newPath);

  external static _renameLink(String oldPath, String newPath);

  File renameSync(String newPath) {
    var result = _rename(_path, newPath);
    throwIfError(result, "Cannot rename file '$_path' to '$newPath'");
    return new File(newPath);
  }

  Directory get directory {
    Path path = new Path(_path).directoryPath;
    return new Directory.fromPath(path);
  }

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

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


  external static _lengthFromPath(String path);

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

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

  external static _lastModified(String path);

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

  external static _open(String path, int mode);

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

  external static int _openStdio(int fd);

  static RandomAccessFile _openStdioSync(int fd) {
    var id = _openStdio(fd);
    if (id == 0) {
      throw new FileException("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] = _path;
    return _fileService.call(request).then((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "Cannot retrieve full path"
                                     " for '$_path'");
      }
      return response;
    });
  }

  external static _fullPath(String path);

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

  Stream<List<int>> openRead([int start, int end]) {
    return new _FileStream(_path, start, end);
  }

  IOSink openWrite({FileMode mode: FileMode.WRITE,
                    Encoding encoding: Encoding.UTF_8}) {
    if (mode != FileMode.WRITE &&
        mode != FileMode.APPEND) {
      throw new FileException(
          "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND");
    }
    var consumer = new _FileStreamConsumer(this, mode);
    return new IOSink(consumer, encoding: encoding);
  }

  Future<List<int>> readAsBytes() {
    _ensureFileService();
    Completer<List<int>> completer = new Completer<List<int>>();
    var chunks = new _BufferList();
    openRead().listen(
      (d) => chunks.add(d),
      onDone: () {
        var result = chunks.readBytes();
        completer.complete(result);
      },
      onError: (e) {
        completer.completeError(e);
      },
      cancelOnError: true);
    return completer.future;
  }

  List<int> readAsBytesSync() {
    var opened = openSync();
    var chunks = new _BufferList();
    var data;
    while ((data = opened.readSync(_BLOCK_SIZE)).length > 0) {
      chunks.add(data);
    }
    opened.closeSync();
    return chunks.readBytes();
  }

  Future<String> readAsString({Encoding encoding: Encoding.UTF_8}) {
    _ensureFileService();
    return readAsBytes().then((bytes) {
      return _decodeString(bytes, encoding);
    });
  }

  String readAsStringSync({Encoding encoding: Encoding.UTF_8}) {
    List<int> bytes = readAsBytesSync();
    return _decodeString(bytes, encoding);
  }

  static List<String> _decodeLines(List<int> bytes, Encoding encoding) {
    if (bytes.length == 0) return [];
    var list = [];
    var controller = new StreamController(sync: true);
    controller.stream
        .transform(new StringDecoder(encoding))
        .transform(new LineTransformer())
        .listen((line) => list.add(line));
    controller.add(bytes);
    controller.close();
    return list;
  }

  Future<List<String>> readAsLines({Encoding encoding: Encoding.UTF_8}) {
    _ensureFileService();
    return readAsBytes().then((bytes) {
      return _decodeLines(bytes, encoding);
    });
  }

  List<String> readAsLinesSync({Encoding encoding: Encoding.UTF_8}) {
    return _decodeLines(readAsBytesSync(), encoding);
  }

  Future<File> writeAsBytes(List<int> bytes,
                            {FileMode mode: FileMode.WRITE}) {
    try {
      IOSink sink = openWrite(mode: mode);
      sink.add(bytes);
      sink.close();
      return sink.done.then((_) => this);
    } catch (e) {
      return new Future.error(e);
    }
  }

  void writeAsBytesSync(List<int> bytes, {FileMode mode: FileMode.WRITE}) {
    RandomAccessFile opened = openSync(mode: mode);
    opened.writeFromSync(bytes, 0, bytes.length);
    opened.closeSync();
  }

  Future<File> writeAsString(String contents,
                             {FileMode mode: FileMode.WRITE,
                              Encoding encoding: Encoding.UTF_8}) {
    try {
      return writeAsBytes(_encodeString(contents, encoding), mode: mode);
    } catch (e) {
      return new Future.error(e);
    }
  }

  void writeAsStringSync(String contents,
                         {FileMode mode: FileMode.WRITE,
                          Encoding encoding: Encoding.UTF_8}) {
    writeAsBytesSync(_encodeString(contents, encoding), mode: mode);
  }

  String get path => _path;

  String toString() => "File: '$path'";

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

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

  final String _path;

  SendPort _fileService;
}


class _RandomAccessFile implements RandomAccessFile {
  _RandomAccessFile(int this._id, String this._path);

  Future<RandomAccessFile> close() {
    if (closed) return _closedException();
    _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).then((result) {
      if (result != -1) {
        _id = result;
        return this;
      } else {
        throw new FileException("Cannot close file '$_path'");
      }
    });
  }

  external static int _close(int id);

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

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

  external static _readByte(int id);

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

  Future<List<int>> read(int bytes) {
    _ensureFileService();
    if (bytes is !int) {
      return new Future.error(new FileException(
          "Invalid arguments to read for file '$_path'"));
    }
    if (closed) return _closedException();
    List request = new List(3);
    request[0] = _READ_REQUEST;
    request[1] = _id;
    request[2] = bytes;
    return _fileService.call(request).then((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "read failed for file '$_path'");
      }
      return response[1];
    });
  }

  external static _read(int id, int bytes);

  List<int> readSync(int bytes) {
    _checkNotClosed();
    if (bytes is !int) {
      throw new FileException(
          "Invalid arguments to readSync for file '$_path'");
    }
    var result = _read(_id, bytes);
    if (result is OSError) {
      throw new FileException("readSync failed for file '$_path'",
                                result);
    }
    return result;
  }

  Future<int> readInto(List<int> buffer, [int start, int end]) {
    _ensureFileService();
    if (buffer is !List ||
        (start != null && start is !int) ||
        (end != null && end is !int)) {
      return new Future.error(new FileException(
          "Invalid arguments to readInto for file '$_path'"));
    };
    if (closed) return _closedException();
    List request = new List(3);
    if (start == null) start = 0;
    if (end == null) end = buffer.length;
    request[0] = _READ_LIST_REQUEST;
    request[1] = _id;
    request[2] = end - start;
    return _fileService.call(request).then((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "readInto failed for file '$_path'");
      }
      var read = response[1];
      var data = response[2];
      buffer.setRange(start, start + read, data);
      return read;
    });
  }

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

  external static _readInto(int id, List<int> buffer, int start, int end);

  int readIntoSync(List<int> buffer, [int start, int end]) {
    _checkNotClosed();
    if (buffer is !List ||
        (start != null && start is !int) ||
        (end != null && end is !int)) {
      throw new FileException(
          "Invalid arguments to readInto for file '$_path'");
    }
    if (start == null) start = 0;
    if (end == null) end = buffer.length;
    if (end == start) return 0;
    _checkReadWriteListArguments(buffer.length, start, end);
    var result = _readInto(_id, buffer, start, end);
    if (result is OSError) {
      throw new FileException("readInto failed for file '$_path'",
                                result);
    }
    return result;
  }

  Future<RandomAccessFile> writeByte(int value) {
    _ensureFileService();
    if (value is !int) {
      return new Future.error(new FileException(
          "Invalid argument to writeByte for file '$_path'"));
    }
    if (closed) return _closedException();
    List request = new List(3);
    request[0] = _WRITE_BYTE_REQUEST;
    request[1] = _id;
    request[2] = value;
    return _fileService.call(request).then((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "writeByte failed for file '$_path'");
      }
      return this;
    });
  }

  external static _writeByte(int id, int value);

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

  Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]) {
    _ensureFileService();
    if ((buffer is !List && buffer is !ByteData) ||
        (start != null && start is !int) ||
        (end != null && end is !int)) {
      return new Future.error(new FileException(
          "Invalid arguments to writeFrom for file '$_path'"));
    }

    if (closed) return _closedException();

    _BufferAndStart result;
    try {
      result = _ensureFastAndSerializableData(buffer, start, end);
    } catch (e) {
      return new Future.error(e);
    }

    List request = new List(5);
    request[0] = _WRITE_LIST_REQUEST;
    request[1] = _id;
    request[2] = result.buffer;
    request[3] = result.start;
    request[4] = end - (start - result.start);
    return _fileService.call(request).then((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "writeFrom failed for file '$_path'");
      }
      return this;
    });
  }

  external static _writeFrom(int id, List<int> buffer, int start, int end);

  void writeFromSync(List<int> buffer, [int start, int end]) {
    _checkNotClosed();
    if (buffer is !List ||
        (start != null && start is !int) ||
        (end != null && end is !int)) {
      throw new FileException(
          "Invalid arguments to writeFrom for file '$_path'");
    }
    if (start == null) start = 0;
    if (end == null) end = buffer.length;
    if (end == start) return;
    _checkReadWriteListArguments(buffer.length, start, end);
    _BufferAndStart bufferAndStart =
        _ensureFastAndSerializableData(buffer, start, end);
    var result = _writeFrom(_id,
                            bufferAndStart.buffer,
                            bufferAndStart.start,
                            end - (start - bufferAndStart.start));
    if (result is OSError) {
      throw new FileException("writeFrom failed for file '$_path'", result);
    }
  }

  Future<RandomAccessFile> writeString(String string,
                                       {Encoding encoding: Encoding.UTF_8}) {
    if (encoding is! Encoding) {
      return new Future.error(new FileException(
          "Invalid encoding in writeString: $encoding"));
    }
    var data = _encodeString(string, encoding);
    return writeFrom(data, 0, data.length);
  }

  void writeStringSync(String string, {Encoding encoding: Encoding.UTF_8}) {
    if (encoding is! Encoding) {
      throw new FileException(
          "Invalid encoding in writeStringSync: $encoding");
    }
    var data = _encodeString(string, encoding);
    writeFromSync(data, 0, data.length);
  }

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

  external static _position(int id);

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

  Future<RandomAccessFile> setPosition(int position) {
    _ensureFileService();
    if (closed) return _closedException();
    List request = new List(3);
    request[0] = _SET_POSITION_REQUEST;
    request[1] = _id;
    request[2] = position;
    return _fileService.call(request).then((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "setPosition failed for file '$_path'");
      }
      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 FileException("setPosition failed for file '$_path'", result);
    }
  }

  Future<RandomAccessFile> truncate(int length) {
    _ensureFileService();
    if (closed) return _closedException();
    List request = new List(3);
    request[0] = _TRUNCATE_REQUEST;
    request[1] = _id;
    request[2] = length;
    return _fileService.call(request).then((response) {
      if (_isErrorResponse(response)) {
        throw _exceptionFromResponse(response,
                                     "truncate failed for file '$_path'");
      }
      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 FileException("truncate failed for file '$_path'", result);
    }
  }

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

  external static _length(int id);

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

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

  external static _flush(int id);

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

  String get path => _path;

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

  bool get closed => _id == 0;

  void _checkNotClosed() {
    if (closed) {
      throw new FileException("File closed '$_path'");
    }
  }

  Future _closedException() {
    return new Future.error(new FileException("File closed '$_path'"));
  }

  final String _path;
  int _id;

  SendPort _fileService;
}
