// Copyright 2016 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:collection';

import 'package:meta/meta.dart';
import 'package:zircon/zircon.dart';

import 'error.dart';
import 'message.dart';

// ignore_for_file: public_member_api_docs

typedef _VoidCallback = void Function();

/// A channel over which messages from interface T can be sent.
///
/// An interface handle holds a [channel] whose peer expects to receive messages
/// from the FIDL interface T. The channel held by an interface handle is not
/// currently bound, which means messages cannot yet be exchanged with the
/// channel's peer.
///
/// To send messages over the channel, bind the interface handle to a `TProxy`
/// object using use [ProxyController<T>.bind] method on the proxy's
/// [Proxy<T>.ctrl] property.
///
/// Example:
///
/// ```dart
/// InterfaceHandle<T> fooHandle = [...]
/// FooProxy foo = new FooProxy();
/// foo.ctrl.bind(fooHandle);
/// foo.bar();
/// ```
///
/// To obtain an interface handle to send over a channel, used the
/// [Binding<T>.wrap] method on an object of type `TBinding`.
///
/// Example:
///
/// ```dart
/// class FooImpl extends Foo {
///   final FooBinding _binding = new FooBinding();
///
///   InterfaceHandle<T> getInterfaceHandle() => _binding.wrap(this);
///
///   @override
///   void bar() {
///     print('Received bar message.');
///   }
/// }
/// ```
class InterfaceHandle<T> {
  /// Creates an interface handle that wraps the given channel.
  InterfaceHandle(this._channel);

  /// The underlying channel messages will be sent over when the interface
  /// handle is bound to a [Proxy].
  ///
  /// To take the channel from this object, use [passChannel].
  Channel get channel => _channel;
  Channel _channel;

  /// Returns [channel] and sets [channel] to `null`.
  ///
  /// Useful for taking ownership of the underlying channel.
  Channel passChannel() {
    final Channel result = _channel;
    _channel = null;
    return result;
  }

  /// Closes the underlying channel.
  void close() {
    _channel?.close();
    _channel = null;
  }
}

/// A channel over which messages from interface T can be received.
///
/// An interface request holds a [channel] whose peer expects to be able to send
/// messages from the FIDL interface T. A channel held by an interface request
/// is not currently bound, which means messages cannot yet be exchanged with
/// the channel's peer.
///
/// To receive messages sent over the channel, bind the interface handle using
/// [Binding<T>.bind] on a `TBinding` object, which you typically hold as a
/// private member variable in a class that implements [T].
///
/// Example:
///
/// ```dart
/// class FooImpl extends Foo {
///   final FooBinding _binding = new FooBinding();
///
///   void bind(InterfaceRequest<T> request) {
///     _binding.bind(request);
///   }
///
///   @override
///   void bar() {
///     print('Received bar message.');
///   }
/// }
/// ```
///
/// To obtain an interface request to send over a channel, used the
/// [ProxyController<T>.request] method on the [Proxy<T>.ctrl] property of an
/// object of type `TProxy`.
///
/// Example:
///
/// ```dart
/// FooProxy foo = new FooProxy();
/// InterfaceRequest<T> request = foo.ctrl.request();
/// ```
class InterfaceRequest<T> {
  /// Creates an interface request that wraps the given channel.
  InterfaceRequest(this._channel);

  /// The underlying channel messages will be received over when the interface
  /// handle is bound to [Binding].
  ///
  /// To take the channel from this object, use [passChannel].
  Channel get channel => _channel;
  Channel _channel;

  /// Returns [channel] and sets [channel] to `null`.
  ///
  /// Useful for taking ownership of the underlying channel.
  Channel passChannel() {
    final Channel result = _channel;
    _channel = null;
    return result;
  }

  /// Closes the underlying channel.
  void close() {
    _channel?.close();
    _channel = null;
  }
}

class InterfacePair<T> {
  InterfacePair() {
    ChannelPair pair = ChannelPair();
    request = InterfaceRequest<T>(pair.first);
    handle = InterfaceHandle<T>(pair.second);
  }

  InterfaceRequest<T> request;
  InterfaceHandle<T> handle;

  InterfaceRequest<T> passRequest() {
    final InterfaceRequest<T> result = request;
    request = null;
    return result;
  }

  InterfaceHandle<T> passHandle() {
    final InterfaceHandle<T> result = handle;
    handle = null;
    return result;
  }
}

/// Listens for messages and dispatches them to an implementation of T.
abstract class Binding<T> {
  /// Creates a binding object in an unbound state.
  ///
  /// Rather than creating a [Binding<T>] object directly, you typically create
  /// a `TBinding` object, which are subclasses of [Binding<T>] created by the
  /// FIDL compiler for a specific interface.
  Binding() {
    _reader
      ..onReadable = _handleReadable
      ..onError = _handleError;
  }

  /// Event for binding.
  _VoidCallback onBind;

  /// Event for unbinding.
  _VoidCallback onUnbind;

  /// Event for when the binding is closed.
  _VoidCallback onClose;

  /// Returns an interface handle whose peer is bound to the given object.
  ///
  /// Creates a channel pair, binds one of the channels to this object, and
  /// returns the other channel. Messages sent over the returned channel will be
  /// decoded and dispatched to `impl`.
  ///
  /// The `impl` parameter must not be null.
  InterfaceHandle<T> wrap(T impl) {
    assert(!isBound);
    ChannelPair pair = ChannelPair();
    if (pair.status != ZX.OK) {
      return null;
    }
    _impl = impl;
    _reader.bind(pair.first);

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

    return InterfaceHandle<T>(pair.second);
  }

  /// Binds the given implementation to the given interface request.
  ///
  /// Listens for messages on channel underlying the given interface request,
  /// decodes them, and dispatches the decoded messages to `impl`.
  ///
  /// This object must not already be bound.
  ///
  /// The `impl` and `interfaceRequest` parameters must not be `null`. The
  /// `channel` property of the given `interfaceRequest` must not be `null`.
  void bind(T impl, InterfaceRequest<T> interfaceRequest) {
    assert(!isBound);
    assert(impl != null);
    assert(interfaceRequest != null);
    Channel channel = interfaceRequest.passChannel();
    assert(channel != null);
    _impl = impl;
    _reader.bind(channel);

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

  /// Unbinds [impl] and returns the unbound channel as an interface request.
  ///
  /// Stops listening for messages on the bound channel, wraps the channel in an
  /// interface request of the appropriate type, and returns that interface
  /// request.
  ///
  /// The object must have previously been bound (e.g., using [bind]).
  InterfaceRequest<T> unbind() {
    assert(isBound);
    final InterfaceRequest<T> result =
        InterfaceRequest<T>(_reader.unbind());
    _impl = null;

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

    return result;
  }

  /// Close the bound channel.
  ///
  /// This function does nothing if the object is not bound.
  void close() {
    if (isBound) {
      _reader.close();
      _impl = null;

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

  /// Called when the channel underneath closes.
  _VoidCallback onConnectionError;

  /// The implementation of [T] bound using this object.
  ///
  /// If this object is not bound, this property is null.
  T get impl => _impl;
  T _impl;

  /// Whether this object is bound to a channel.
  ///
  /// See [bind] and [unbind] for more information.
  bool get isBound => _impl != null;

  /// Decodes the given message and dispatches the decoded message to [impl].
  ///
  /// This function is called by this object whenever a message arrives over a
  /// bound channel.
  @protected
  void handleMessage(Message message, MessageSink respond);

  void _handleReadable() {
    final ReadResult result = _reader.channel.queryAndRead();
    if ((result.bytes == null) || (result.bytes.lengthInBytes == 0))
      throw FidlError('Unexpected empty message or error: $result '
          'from channel ${_reader.channel}');

    final Message message = Message.fromReadResult(result);
    handleMessage(message, sendMessage);
  }

  /// Always called when the channel underneath closes. If [onConnectionError]
  /// is set, it is called.
  void _handleError(ChannelReaderError error) {
    if (onConnectionError != null) {
      onConnectionError();
    }
  }

  /// Sends the given message over the bound channel.
  ///
  /// If the channel is not bound, the handles inside the message are closed and
  /// the message itself is discarded.
  void sendMessage(Message response) {
    if (!_reader.isBound) {
      response.closeHandles();
      return;
    }
    _reader.channel.write(response.data, response.handles);
  }

  final ChannelReader _reader = ChannelReader();
}

/// The object that [ProxyController<T>.error] completes with when there is
/// an error.
class ProxyError {
  /// Creates a proxy error with the given message.
  ///
  /// The `message` argument must not be null.
  ProxyError(this.message);

  /// What went wrong.
  final String message;

  @override
  String toString() => 'ProxyError: $message';
}

/// The control plane for an interface proxy.
///
/// A proxy controller lets you operate on the local [Proxy<T>] object itself
/// rather than send messages to the remote implementation of the proxy. For
/// example, you can [unbind] or [close] the proxy.
///
/// You typically obtain a [ProxyController<T>] object as the [Proxy<T>.ctrl]
/// property of a `TProxy` object.
///
/// Example:
///
/// ```dart
/// FooProxy foo = new FooProxy();
/// fooProvider.getFoo(foo.ctrl.request());
/// ```
class ProxyController<T> {
  /// Creates proxy controller.
  ///
  /// Proxy controllers are not typically created directly. Instead, you
  /// typically obtain a [ProxyController<T>] object as the [Proxy<T>.ctrl]
  /// property of a `TProxy` object.
  ProxyController({this.$serviceName, this.$interfaceName}) {
    _reader
      ..onReadable = _handleReadable
      ..onError = _handleError;
  }

  /// Event for binding.
  _VoidCallback onBind;

  /// Event for unbinding.
  _VoidCallback onUnbind;

  /// Event for when the binding is closed.
  _VoidCallback onClose;

  /// The service name associated with [T], if any.
  ///
  /// Will be set if the `[Discoverable]` attribute is on the FIDL interface
  /// definition. If set it will be the fully-qualified name of the interface.
  ///
  /// This string is typically used with the `ServiceProvider` interface to
  /// request an implementation of [T].
  final String $serviceName;

  /// The name of the interface of [T].
  ///
  /// Unlike [$serviceName] should always be set and won't be fully qualified.
  /// This should only be used for debugging and logging purposes.
  final String $interfaceName;

  /// Creates an interface request whose peer is bound to this interface proxy.
  ///
  /// Creates a channel pair, binds one of the channels to this object, and
  /// returns the other channel. Calls to the proxy will be encoded as messages
  /// and sent to the returned channel.
  ///
  /// The proxy must not already have been bound.
  InterfaceRequest<T> request() {
    assert(!isBound);
    ChannelPair pair = ChannelPair();
    assert(pair.status == ZX.OK);
    _reader.bind(pair.first);

    _boundCompleter.complete();
    if (onBind != null) {
      onBind();
    }

    return InterfaceRequest<T>(pair.second);
  }

  /// Binds the proxy to the given interface handle.
  ///
  /// Calls to the proxy will be encoded as messages and sent over the channel
  /// underlying the given interface handle.
  ///
  /// This object must not already be bound.
  ///
  /// The `interfaceHandle` parameter must not be null. The `channel` property
  /// of the given `interfaceHandle` must not be null.
  void bind(InterfaceHandle<T> interfaceHandle) {
    assert(!isBound);
    assert(interfaceHandle != null);
    assert(interfaceHandle.channel != null);
    _reader.bind(interfaceHandle.passChannel());

    _boundCompleter.complete();
    if (onBind != null) {
      onBind();
    }
  }

  /// Unbinds the proxy and returns the unbound channel as an interface handle.
  ///
  /// Calls on the proxy will no longer be encoded as messages on the bound
  /// channel.
  ///
  /// The proxy must have previously been bound (e.g., using [bind]).
  InterfaceHandle<T> unbind() {
    assert(isBound);
    if (!_reader.isBound) {
      return null;
    }

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

    // TODO(rosswang): Do we need to _reset() here?
    return InterfaceHandle<T>(_reader.unbind());
  }

  /// Whether this object is bound to a channel.
  ///
  /// See [bind] and [unbind] for more information.
  bool get isBound => _reader.isBound;

  /// Close the channel bound to the proxy.
  ///
  /// The proxy must have previously been bound (e.g., using [bind]).
  void close() {
    if (isBound) {
      if (_pendingResponsesCount > 0) {
        proxyError('The proxy is closed.');
      }
      _reset();
      _reader.close();

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

  /// Called when the channel underneath closes.
  _VoidCallback onConnectionError;

  /// Called whenever this object receives a response on a bound channel.
  ///
  /// Used by subclasses of [Proxy<T>] to receive responses to messages.
  MessageSink onResponse;

  final ChannelReader _reader = ChannelReader();
  final HashMap<int, Function> _callbackMap = HashMap<int, Function>();

  /// A future that completes when an error is generated by the proxy.
  Future<ProxyError> get error => _errorCompleter.future;
  Completer<ProxyError> _errorCompleter = Completer<ProxyError>();

  /// A future that completes when the proxy is bound.
  Future<Null> get bound => _boundCompleter.future;
  Completer<Null> _boundCompleter = Completer<Null>();

  int _nextTxid = 1;
  int _pendingResponsesCount = 0;

  void _reset() {
    _callbackMap.clear();
    _errorCompleter = Completer<ProxyError>();
    if (!_boundCompleter.isCompleted) {
      _boundCompleter.completeError('Proxy<${$interfaceName}> closed.');
    }
    _boundCompleter = Completer<Null>();
    _nextTxid = 1;
    _pendingResponsesCount = 0;
  }

  void _handleReadable() {
    final ReadResult result = _reader.channel.queryAndRead();
    if ((result.bytes == null) || (result.bytes.lengthInBytes == 0)) {
      proxyError('Read from channel ${_reader.channel} failed');
      return;
    }
    try {
      _pendingResponsesCount--;
      if (onResponse != null) {
        onResponse(Message.fromReadResult(result));
      }
    } on FidlError catch (e) {
      if (result.handles != null) {
        for (Handle handle in result.handles) {
          handle.close();
        }
      }
      proxyError(e.toString());
      close();
    }
  }

  /// Always called when the channel underneath closes. If [onConnectionError]
  /// is set, it is called.
  void _handleError(ChannelReaderError error) {
    proxyError(error.toString());
    _reset();
    if (onConnectionError != null) {
      onConnectionError();
    }
  }

  /// Sends the given messages over the bound channel.
  ///
  /// Used by subclasses of [Proxy<T>] to send encoded messages.
  void sendMessage(Message message) {
    if (!_reader.isBound) {
      proxyError('The proxy is closed.');
      return;
    }
    final int status = _reader.channel.write(message.data, message.handles);
    if (status != ZX.OK)
      proxyError(
          'Failed to write to channel: ${_reader.channel} (status: $status)');
  }

  /// Sends the given messages over the bound channel and registers a callback
  /// to handle the response.
  ///
  /// Used by subclasses of [Proxy<T>] to send encoded messages.
  void sendMessageWithResponse(Message message, Function callback) {
    if (!_reader.isBound) {
      proxyError('The sender is closed.');
      return;
    }

    const int _kUserspaceTxidMask = 0x7FFFFFFF;

    int txid = _nextTxid++ & _kUserspaceTxidMask;
    while (txid == 0 || _callbackMap.containsKey(txid))
      txid = _nextTxid++ & _kUserspaceTxidMask;
    message.txid = txid;
    final int status = _reader.channel.write(message.data, message.handles);

    if (status != ZX.OK) {
      proxyError(
          'Failed to write to channel: ${_reader.channel} (status: $status)');
      return;
    }

    _callbackMap[message.txid] = callback;
    _pendingResponsesCount++;
  }

  /// Returns the callback associated with the given response message.
  ///
  /// Used by subclasses of [Proxy<T>] to retrieve registered callbacks when
  /// handling response messages.
  Function getCallback(int txid) {
    final Function result = _callbackMap.remove(txid);
    if (result == null) {
      proxyError('Message had unknown request id: $txid');
      return null;
    }
    return result;
  }

  /// Complete the [error] future with the given message.
  void proxyError(String message) {
    final fullMessage =
        'Error in proxy with interface name [${$interfaceName}] and '
        'service name [${$serviceName}]: $message';
    print(fullMessage);
    if (!_errorCompleter.isCompleted) {
      error.whenComplete(() {
        _errorCompleter = Completer<ProxyError>();
      });
      _errorCompleter.complete(ProxyError(fullMessage));
    }
  }
}

/// Sends messages to a remote implementation of [T]
class Proxy<T> {
  /// Creates a proxy object with the given [ctrl].
  ///
  /// Rather than creating [Proxy<T>] object directly, you typically create
  /// `TProxy` objects, which are subclasses of [Proxy<T>] created by the FIDL
  /// compiler for a specific interface.
  Proxy(this.ctrl);

  /// The control plane for this proxy.
  ///
  /// Methods that manipulate the local proxy (as opposed to sending messages
  /// to the remote implementation of [T]) are exposed on this [ctrl] object to
  /// avoid naming conflicts with the methods of [T].
  final ProxyController<T> ctrl;

  // In general it's probably better to avoid adding fields and methods to this
  // class. Names added to this class have to be mangled by bindings generation
  // to avoid name conflicts.
}
