// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:math';
import 'dart:typed_data';

import 'package:fidl/fidl.dart' as fidl;
import 'package:fidl_fuchsia_io/fidl_async.dart';
import 'package:meta/meta.dart';
import 'package:zircon/zircon.dart';

import 'vnode.dart';

typedef WriteFn = int Function(Uint8List);
typedef WriteFnStr = int Function(String);
typedef ReadFn = Uint8List Function();
typedef ReadFnStr = String Function();

/// A [PseudoFile] is a file-like object whose content is generated and modified
/// dynamically on-the-fly by invoking handler functions rather than being
/// directly persisted as a sequence of bytes.
///
/// This class is designed to allow programs to publish read-only,
/// or read-write properties such as configuration options, debug flags,
/// and dumps of internal state which may change dynamically.
///
/// Although [PseudoFile] usually contain text, they can also be used for binary
/// data.
///
/// Read callback, is called when the connection to the file is opened and
/// pre-populates a buffer that will be used to when serving this file content
/// over this particular connection.
///
/// Write callback, if any, is called when the connection is closed if the file
/// content was ever modified while the connection was open.
/// Modifications are: [fuchsia.io.File#write()] calls or opening a file for
/// writing with the `openFlagTruncate` flag set.
class PseudoFile extends Vnode {
  final int _capacity;
  ReadFn _readFn;
  WriteFn _writeFn;
  final List<_FileConnection> _connections = [];

  /// Creates a new read-only [PseudoFile] backed by the specified read handler.
  ///
  /// The handler is called every time a read operation is performed on the file.  It is only allowed
  /// to read at offset 0, and all of the content returned by the handler is returned by the read
  /// operation.  Subsequent reads act the same - there is no seek position, nor ability to read
  /// content in chunks.
  PseudoFile.readOnly(this._readFn)
      : _capacity = 0,
        assert(_readFn != null);

  /// See [#readOnly()].  Wraps the callback, allowing it to return a String instead of a Uint8List,
  /// but otherwise behaves identical to [#readOnly()].
  PseudoFile.readOnlyStr(ReadFnStr fn)
      : _capacity = 0,
        assert(fn != null) {
    _readFn = _getReadFn(fn);
  }

  /// Creates new [PseudoFile] backed by the specified read and write handlers.
  ///
  /// The read handler is called every time a read operation is performed on the file.  It is only
  /// allowed to read at offset 0, and all of the content returned by the handler is returned by the
  /// read operation.  Subsequent reads act the same - there is no seek position, nor ability to read
  /// content in chunks.
  ///
  /// The write handler is called every time a write operation is performed on the file.  It is only
  /// allowed to write at offset 0, and all of the new content should be provided to a single write
  /// operation.  Subsequent writes act the same - there is no seek position, nor ability to write
  /// content in chunks.
  PseudoFile.readWrite(this._capacity, this._readFn, this._writeFn)
      : assert(_writeFn != null),
        assert(_readFn != null),
        assert(_capacity > 0);

  /// See [#readWrite()].  Wraps the read callback, allowing it to return a [String] instead of a
  /// [Uint8List].  Wraps the write callback, only allowing valid UTF-8 content to be written into
  /// the file.  Written bytes are converted into a string instance, and the passed to the handler.
  /// In every other aspect behaves just like [#readWrite()].
  PseudoFile.readWriteStr(this._capacity, ReadFnStr rfn, WriteFnStr wfn)
      : assert(_capacity > 0),
        assert(rfn != null),
        assert(wfn != null) {
    _readFn = _getReadFn(rfn);
    _writeFn = _getWriteFn(wfn);
  }

  /// Connects to this instance of [PseudoFile] and serves [fushsia.io.File] over fidl.
  @override
  int connect(int flags, int mode, fidl.InterfaceRequest<Node> request,
      [int parentFlags = -1]) {
    // There should be no MODE_TYPE_* flags set, except for, possibly,
    // MODE_TYPE_FILE when the target is a pseudo file.
    if ((mode & ~modeProtectionMask) & ~modeTypeFile != 0) {
      sendErrorEvent(flags, ZX.ERR_INVALID_ARGS, request);
      return ZX.ERR_INVALID_ARGS;
    }

    var status = _validateFlags(parentFlags, flags);
    if (status != ZX.OK) {
      sendErrorEvent(flags, status, request);
      return status;
    }

    var connection = _FileConnection(
        capacity: _capacity,
        flags: flags,
        file: this,
        mode: mode,
        request: fidl.InterfaceRequest<File>(request.passChannel()));

    // [connection] will also send on_open success event.
    _connections.add(connection);
    return ZX.OK;
  }

  @override
  int inodeNumber() {
    return inoUnknown;
  }

  @override
  int type() {
    return direntTypeFile;
  }

  ReadFn _getReadFn(ReadFnStr fn) {
    return () => Uint8List.fromList(fn().codeUnits);
  }

  WriteFn _getWriteFn(WriteFnStr fn) {
    return (Uint8List buffer) => fn(String.fromCharCodes(buffer));
  }

  void _onClose(_FileConnection obj) {
    assert(_connections.remove(obj));
  }

  int _validateFlags(int parentFlags, int flags) {
    if (flags & openFlagDirectory != 0) {
      return ZX.ERR_NOT_DIR;
    }
    var allowedFlags = openFlagDescribe;
    if (_readFn != null) {
      allowedFlags |= openRightReadable;
    }
    if (_writeFn != null) {
      allowedFlags |= openRightWritable | openFlagTruncate;
    }

    // allowedFlags takes precedence over prohibited_flags.
    var prohibitedFlags = openFlagAppend;

    var flagsDependentOnParentFlags = [openRightReadable, openRightWritable];
    for (var flag in flagsDependentOnParentFlags) {
      if (flags & flag != 0 && parentFlags & flag == 0) {
        return ZX.ERR_ACCESS_DENIED;
      }
    }

    if (flags & prohibitedFlags != 0) {
      return ZX.ERR_INVALID_ARGS;
    }
    if (flags & ~allowedFlags != 0) {
      return ZX.ERR_NOT_SUPPORTED;
    }
    return ZX.OK;
  }
}

/// Implementation of fuchsia.io.File for pseudo file.
///
/// This class should not be used directly, but by [fuchsia_vfs.PseudoFile].
class _FileConnection extends File {
  final FileBinding _binding = new FileBinding();

  /// open file connection flags
  final int flags;

  /// open file mode
  final int mode;

  /// seek position in file.
  int seekPos = 0;

  /// file's maximum capacity.
  int capacity;

  /// current length of file.
  int _currentLen = 0;

  // TODO(CF-252): Implement a grow-able buffer.
  /// buffer which stores file content
  Uint8List _buffer = Uint8List(0);

  /// true if client wrote to this file.
  bool _wasWritten = false;

  /// Reference to PsuedoFile's Vnode.
  PseudoFile file;

  bool _closed = false;

  /// Constructor to init _FileConnection
  _FileConnection({
    @required this.flags,
    @required this.mode,
    @required this.capacity,
    @required this.file,
    @required fidl.InterfaceRequest<File> request,
  }) : assert(file != null) {
    if (file._writeFn != null) {
      _buffer = Uint8List(capacity);
    }

    if (flags & openFlagTruncate != 0) {
      // don't call read handler on truncate.
      _wasWritten = true;
    } else {
      var readBuf = file._readFn();
      _currentLen = readBuf.lengthInBytes;
      if (_currentLen > capacity) {
        capacity = _currentLen;
        _buffer = Uint8List(capacity);
      }
      _buffer.setRange(0, _currentLen, readBuf);
    }
    _binding.bind(this, request);
    _binding.whenClosed.then((_) => close());
  }

  @override
  Stream<File$OnOpen$Response> get onOpen {
    if ((flags & openFlagDescribe) == 0) {
      return null;
    }
    NodeInfo nodeInfo = _describe();
    var d = File$OnOpen$Response(ZX.OK, nodeInfo);
    return Stream.fromIterable([d]);
  }

  @override
  Future<void> clone(int flags, fidl.InterfaceRequest<Node> object) async {
    file.connect(flags, mode, object, this.flags);
  }

  @override
  Future<int> close() async {
    if (_closed) {
      return ZX.OK;
    }
    var status = ZX.OK;
    if (file._writeFn != null && _wasWritten) {
      status = file._writeFn(_buffer.buffer.asUint8List(0, _currentLen));
    }
    // no more read/write operations should be possible
    file._onClose(this);
    _closed = true;
    return status;
  }

  @override
  Future<NodeInfo> describe() async {
    return _describe();
  }

  @override
  Future<File$GetAttr$Response> getAttr() async {
    return File$GetAttr$Response(
        ZX.ERR_NOT_SUPPORTED,
        NodeAttributes(
            mode: modeTypeFile | modeProtectionMask,
            id: inoUnknown,
            contentSize: 0,
            storageSize: 0,
            linkCount: 1,
            creationTime: 0,
            modificationTime: 0));
  }

  @override
  Future<File$GetFlags$Response> getFlags() async {
    return File$GetFlags$Response(ZX.OK, flags);
  }

  @override
  Future<File$GetVmo$Response> getVmo(int flags) async {
    return File$GetVmo$Response(ZX.OK, null);
  }

  @override
  Future<File$Ioctl$Response> ioctl(
      int opcode, int maxOut, List<Handle> handles, Uint8List in$) async {
    return File$Ioctl$Response(ZX.ERR_NOT_SUPPORTED, [], Uint8List(0));
  }

  @override
  Future<File$Read$Response> read(int count) async {
    var response = _handleRead(count, seekPos);
    if (response.s == ZX.OK) {
      seekPos += response.data.length;
    }
    return response;
  }

  @override
  Future<File$ReadAt$Response> readAt(int count, int offset) async {
    var response = _handleRead(count, offset);
    return File$ReadAt$Response(response.s, response.data);
  }

  @override
  Future<File$Seek$Response> seek(int offset, SeekOrigin seek) async {
    var calculatedOffset = offset;
    switch (seek) {
      case SeekOrigin.start:
        calculatedOffset = offset;
        break;
      case SeekOrigin.current:
        calculatedOffset = seekPos + offset;
        break;
      case SeekOrigin.end:
        calculatedOffset = (_currentLen - 1) + offset;
        break;
      default:
        return File$Seek$Response(ZX.ERR_INVALID_ARGS, 0);
    }
    if (calculatedOffset > _currentLen || calculatedOffset < 0) {
      return File$Seek$Response(ZX.ERR_OUT_OF_RANGE, seekPos);
    }
    seekPos = calculatedOffset;
    return File$Seek$Response(ZX.OK, seekPos);
  }

  @override
  Future<int> setAttr(int flags, NodeAttributes attributes) async {
    return ZX.ERR_NOT_SUPPORTED;
  }

  @override
  Future<int> setFlags(int flags) async {
    return ZX.ERR_NOT_SUPPORTED;
  }

  @override
  Future<int> sync() async {
    return ZX.ERR_NOT_SUPPORTED;
  }

  @override
  Future<int> truncate(int length) async {
    if ((flags & openRightWritable) == 0) {
      return ZX.ERR_ACCESS_DENIED;
    }
    if (file._writeFn == null) {
      return ZX.ERR_NOT_SUPPORTED;
    }
    if (length > _currentLen) {
      return ZX.ERR_OUT_OF_RANGE;
    }

    _currentLen = length;
    seekPos = min(seekPos, _currentLen);
    _wasWritten = true;
    return ZX.OK;
  }

  @override
  Future<File$Write$Response> write(Uint8List data) async {
    var response = _handleWrite(seekPos, data);
    if (response.s == ZX.OK) {
      seekPos += response.actual;
    }
    return response;
  }

  @override
  Future<File$WriteAt$Response> writeAt(Uint8List data, int offset) async {
    var response = _handleWrite(offset, data);
    return File$WriteAt$Response(response.s, response.actual);
  }

  NodeInfo _describe() {
    return NodeInfo.withFile(FileObject(event: null));
  }

  File$Read$Response _handleRead(int count, int offset) {
    if ((flags & openRightReadable) == 0) {
      return File$Read$Response(ZX.ERR_ACCESS_DENIED, Uint8List(0));
    }
    if (file._readFn == null) {
      return File$Read$Response(ZX.ERR_NOT_SUPPORTED, Uint8List(0));
    }
    if (offset == _currentLen) {
      return File$Read$Response(ZX.OK, Uint8List(0));
    }
    if (offset > _currentLen) {
      return File$Read$Response(ZX.ERR_OUT_OF_RANGE, Uint8List(0));
    }

    var c = count;
    if (count + offset > _currentLen) {
      c = _currentLen - offset;
      if (c < 0) {
        c = 0;
      }
    }
    var b = Uint8List.view(_buffer.buffer, offset, c);
    return File$Read$Response(ZX.OK, b);
  }

  File$Write$Response _handleWrite(int offset, Uint8List data) {
    if ((flags & openRightWritable) == 0) {
      return File$Write$Response(ZX.ERR_ACCESS_DENIED, 0);
    }
    if (file._writeFn == null) {
      return File$Write$Response(ZX.ERR_NOT_SUPPORTED, 0);
    }
    if (offset >= capacity) {
      return File$Write$Response(ZX.ERR_OUT_OF_RANGE, 0);
    }
    if (offset > _currentLen) {
      return File$Write$Response(ZX.ERR_OUT_OF_RANGE, 0);
    }

    var actual = min(data.length, capacity - offset);
    _buffer.setRange(offset, offset + actual, data.getRange(0, actual));
    _wasWritten = true;
    _currentLen = offset + actual;
    return File$Write$Response(ZX.OK, actual);
  }
}
