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

// @dart=2.10
import 'dart:convert';
import 'dart:math' as math show min;
import 'dart:typed_data';

import 'package:file/src/common.dart' as common;
import 'package:file/src/io.dart' as io;

import 'memory_file.dart';
import 'node.dart';
import 'utils.dart' as utils;

/// A [MemoryFileSystem]-backed implementation of [io.RandomAccessFile].
class MemoryRandomAccessFile implements io.RandomAccessFile {
  /// Constructs a [MemoryRandomAccessFile].
  ///
  /// This should be used only by [MemoryFile.open] or [MemoryFile.openSync].
  MemoryRandomAccessFile(this.path, this._node, this._mode) {
    switch (_mode) {
      case io.FileMode.read:
        break;
      case io.FileMode.write:
      case io.FileMode.writeOnly:
        truncateSync(0);
        break;
      case io.FileMode.append:
      case io.FileMode.writeOnlyAppend:
        _position = lengthSync();
        break;
      default:
        // [FileMode] provides no way of retrieving its value or name.
        throw UnimplementedError('Unsupported FileMode');
    }
  }

  @override
  final String path;

  final FileNode _node;
  final io.FileMode _mode;

  bool _isOpen = true;
  int _position = 0;

  /// Whether an asynchronous operation is pending.
  ///
  /// See [_asyncWrapper] for details.
  bool get _asyncOperationPending => __asyncOperationPending;

  set _asyncOperationPending(bool value) {
    assert(__asyncOperationPending != value);
    __asyncOperationPending = value;
  }

  bool __asyncOperationPending = false;

  /// Throws a [io.FileSystemException] if an operation is attempted on a file
  /// that is not open.
  void _checkOpen() {
    if (!_isOpen) {
      throw io.FileSystemException('File closed', path);
    }
  }

  /// Throws a [io.FileSystemException] if attempting to read from a file that
  /// has not been opened for reading.
  void _checkReadable(String operation) {
    switch (_mode) {
      case io.FileMode.read:
      case io.FileMode.write:
      case io.FileMode.append:
        return;
      case io.FileMode.writeOnly:
      case io.FileMode.writeOnlyAppend:
      default:
        throw io.FileSystemException(
            '$operation failed', path, common.badFileDescriptor(path).osError);
    }
  }

  /// Throws a [io.FileSystemException] if attempting to read from a file that
  /// has not been opened for writing.
  void _checkWritable(String operation) {
    if (utils.isWriteMode(_mode)) {
      return;
    }

    throw io.FileSystemException(
        '$operation failed', path, common.badFileDescriptor(path).osError);
  }

  /// Throws a [io.FileSystemException] if attempting to perform an operation
  /// while an asynchronous operation is already in progress.
  ///
  /// See [_asyncWrapper] for details.
  void _checkAsync() {
    if (_asyncOperationPending) {
      throw io.FileSystemException(
          'An async operation is currently pending', path);
    }
  }

  /// Wraps a synchronous function to make it appear asynchronous.
  ///
  /// [_asyncOperationPending], [_checkAsync], and [_asyncWrapper] are used to
  /// mimic [RandomAccessFile]'s enforcement that only one asynchronous
  /// operation is pending for a [RandomAccessFile] instance.  Since
  /// [MemoryFileSystem]-based classes are likely to be used in tests, fidelity
  /// is important to catch errors that might occur in production.
  ///
  /// [_asyncWrapper] does not call [f] directly since setting and unsetting
  /// [_asyncOperationPending] synchronously would not be meaningful.  We
  /// instead execute [f] through a [Future.delayed] callback to better simulate
  /// asynchrony.
  Future<R> _asyncWrapper<R>(R Function() f) async {
    _checkAsync();

    _asyncOperationPending = true;
    try {
      return await Future<R>.delayed(
        Duration.zero,
        () {
          // Temporarily reset [_asyncOpPending] in case [f]'s has its own
          // checks for pending asynchronous operations.
          _asyncOperationPending = false;
          try {
            return f();
          } finally {
            _asyncOperationPending = true;
          }
        },
      );
    } finally {
      _asyncOperationPending = false;
    }
  }

  @override
  Future<void> close() async => _asyncWrapper(closeSync);

  @override
  void closeSync() {
    _checkOpen();
    _isOpen = false;
  }

  @override
  Future<io.RandomAccessFile> flush() async {
    await _asyncWrapper(flushSync);
    return this;
  }

  @override
  void flushSync() {
    _checkOpen();
    _checkAsync();
  }

  @override
  Future<int> length() => _asyncWrapper(lengthSync);

  @override
  int lengthSync() {
    _checkOpen();
    _checkAsync();
    return _node.size;
  }

  @override
  Future<io.RandomAccessFile> lock([
    io.FileLock mode = io.FileLock.exclusive,
    int start = 0,
    int end = -1,
  ]) async {
    await _asyncWrapper(() => lockSync(mode, start, end));
    return this;
  }

  @override
  void lockSync([
    io.FileLock mode = io.FileLock.exclusive,
    int start = 0,
    int end = -1,
  ]) {
    _checkOpen();
    _checkAsync();
    // TODO(jamesderlin): Implement, https://github.com/google/file.dart/issues/140
    throw UnimplementedError('TODO');
  }

  @override
  Future<int> position() => _asyncWrapper(positionSync);

  @override
  int positionSync() {
    _checkOpen();
    _checkAsync();
    return _position;
  }

  @override
  Future<Uint8List> read(int bytes) => _asyncWrapper(() => readSync(bytes));

  @override
  Uint8List readSync(int bytes) {
    _checkOpen();
    _checkAsync();
    _checkReadable('read');
    // TODO(jamesderlin): Check for integer overflow.
    final int end = math.min(_position + bytes, lengthSync());
    final Uint8List copy = _node.content.sublist(_position, end);
    _position = end;
    return copy;
  }

  @override
  Future<int> readByte() => _asyncWrapper(readByteSync);

  @override
  int readByteSync() {
    _checkOpen();
    _checkAsync();
    _checkReadable('readByte');

    if (_position >= lengthSync()) {
      return -1;
    }
    return _node.content[_position++];
  }

  @override
  Future<int> readInto(List<int> buffer, [int start = 0, int? end]) =>
      _asyncWrapper(() => readIntoSync(buffer, start, end));

  @override
  int readIntoSync(List<int> buffer, [int start = 0, int? end]) {
    _checkOpen();
    _checkAsync();
    _checkReadable('readInto');

    end = RangeError.checkValidRange(start, end, buffer.length);

    final int length = lengthSync();
    int i;
    for (i = start; i < end && _position < length; i += 1, _position += 1) {
      buffer[i] = _node.content[_position];
    }
    return i - start;
  }

  @override
  Future<io.RandomAccessFile> setPosition(int position) async {
    await _asyncWrapper(() => setPositionSync(position));
    return this;
  }

  @override
  void setPositionSync(int position) {
    _checkOpen();
    _checkAsync();

    if (position < 0) {
      throw io.FileSystemException(
          'setPosition failed', path, common.invalidArgument(path).osError);
    }

    // Empirical testing indicates that setting the position to be beyond the
    // end of the file is legal and will zero-fill upon the next write.
    _position = position;
  }

  @override
  Future<io.RandomAccessFile> truncate(int length) async {
    await _asyncWrapper(() => truncateSync(length));
    return this;
  }

  @override
  void truncateSync(int length) {
    _checkOpen();
    _checkAsync();

    if (length < 0 || !utils.isWriteMode(_mode)) {
      throw io.FileSystemException(
          'truncate failed', path, common.invalidArgument(path).osError);
    }

    final int oldLength = lengthSync();
    if (length < oldLength) {
      _node.truncate(length);

      // [_position] is intentionally left untouched to match the observed
      // behavior of [RandomAccessFile].
    } else if (length > oldLength) {
      _node.write(Uint8List(length - oldLength));
    }
    assert(lengthSync() == length);
  }

  @override
  Future<io.RandomAccessFile> unlock([int start = 0, int end = -1]) async {
    await _asyncWrapper(() => unlockSync(start, end));
    return this;
  }

  @override
  void unlockSync([int start = 0, int end = -1]) {
    _checkOpen();
    _checkAsync();
    // TODO(jamesderlin): Implement, https://github.com/google/file.dart/issues/140
    throw UnimplementedError('TODO');
  }

  @override
  Future<io.RandomAccessFile> writeByte(int value) async {
    await _asyncWrapper(() => writeByteSync(value));
    return this;
  }

  @override
  int writeByteSync(int value) {
    _checkOpen();
    _checkAsync();
    _checkWritable('writeByte');

    // [Uint8List] will truncate values to 8-bits automatically, so we don't
    // need to check [value].

    int length = lengthSync();
    if (_position >= length) {
      // If [_position] is out of bounds, [RandomAccessFile] zero-fills the
      // file.
      truncateSync(_position + 1);
      length = lengthSync();
    }
    assert(_position < length);
    _node.content[_position++] = value;

    // Despite what the documentation states, [RandomAccessFile.writeByteSync]
    // always seems to return 1, even if we had to extend the file for an out of
    // bounds write.  See https://github.com/dart-lang/sdk/issues/42298.
    return 1;
  }

  @override
  Future<io.RandomAccessFile> writeFrom(
    List<int> buffer, [
    int start = 0,
    int? end,
  ]) async {
    await _asyncWrapper(() => writeFromSync(buffer, start, end));
    return this;
  }

  @override
  void writeFromSync(List<int> buffer, [int start = 0, int? end]) {
    _checkOpen();
    _checkAsync();
    _checkWritable('writeFrom');

    end = RangeError.checkValidRange(start, end, buffer.length);

    final int writeByteCount = end - start;
    final int endPosition = _position + writeByteCount;

    if (endPosition > lengthSync()) {
      truncateSync(endPosition);
    }

    _node.content.setRange(_position, endPosition, buffer, start);
    _position = endPosition;
  }

  @override
  Future<io.RandomAccessFile> writeString(
    String string, {
    Encoding encoding = utf8,
  }) async {
    await _asyncWrapper(() => writeStringSync(string, encoding: encoding));
    return this;
  }

  @override
  void writeStringSync(String string, {Encoding encoding = utf8}) {
    writeFromSync(encoding.encode(string));
  }
}
