// 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 'package:fidl/fidl.dart';
import 'package:lib.app.dart/logging.dart';
import 'package:fidl_fuchsia_modular/fidl.dart' as fidl;

import 'entity_client.dart';

/// Client wrapper for [fidl.EntityResolver].
class EntityResolverClient {
  /// The underlying [Proxy] used to send client requests to the
  /// [fidl.EntityResolver] service.
  final fidl.EntityResolverProxy proxy = fidl.EntityResolverProxy();

  final List<EntityClient> _entities = <EntityClient>[];

  /// Constructor.
  EntityResolverClient() {
    proxy.ctrl
      ..onBind = _handleBind
      ..onClose = _handleClose
      ..onConnectionError = _handleConnectionError
      ..onUnbind = _handleUnbind;
  }

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

  /// See [fidl.EntityResolver#resolveEntity].
  Future<EntityClient> resolveEntity(String ref) async {
    Completer<EntityClient> completer = Completer<EntityClient>();

    try {
      await bound;
    } on Exception catch (err, stackTrace) {
      completer.completeError(err, stackTrace);
    }

    EntityClient entity = EntityClient();

    // ignore: unawaited_futures
    proxy.ctrl.error.then((ProxyError err) {
      if (!completer.isCompleted) {
        completer.completeError(err);
      }
    });

    // ignore: unawaited_futures
    entity.proxy.ctrl.error.then((ProxyError err) {
      if (!completer.isCompleted) {
        completer.completeError(err);
      }
    });

    _entities.add(entity); // don't forget to close.

    try {
      proxy.resolveEntity(ref, entity.proxy.ctrl.request());
    } on Exception catch (err, stackTrace) {
      completer.completeError(err, stackTrace);
    }

    scheduleMicrotask(() {
      if (!completer.isCompleted) {
        completer.complete(entity);
      }
    });

    return completer.future;
  }

  /// Closes the underlying proxy connection, should be called as a response to
  /// Lifecycle::terminate (see https://goo.gl/MmZ2dc).
  Future<Null> terminate() async {
    log.info('terminate called');
    proxy.ctrl.close();
    return;
  }

  void _handleBind() {
    log.fine('proxy ready');
    _bind.complete(null);
  }

  void _handleUnbind() {
    log.fine('proxy unbound');
  }

  void _handleClose() {
    log.fine('proxy closed');

    for (EntityClient entity in _entities) {
      entity.terminate();
    }
  }

  void _handleConnectionError() {
    log.severe('EntityResolverClient connection error');
  }
}
