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

export 'package:fidl_fuchsia_modular/fidl.dart' show ModuleState;

/// Client wrapper for [fidl.ModuleController].
class ModuleControllerClient {
  /// The underlying [fidl.ModuleControllerProxy] used to send client requests
  /// to the [fidl.ModuleController] service.
  final fidl.ModuleControllerProxy proxy = fidl.ModuleControllerProxy();

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

  final Completer<Null> _bind = Completer<Null>();

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

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

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

  void _handleClose() {
    log.fine('proxy closed, terminating link clients');
  }

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

  /// Focus the module.
  Future<Null> focus() async {
    Completer<Null> completer = Completer<Null>();

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

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

    return completer.future;
  }

  /// Defocus the module.
  Future<Null> defocus() async {
    Completer<Null> completer = Completer<Null>();

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

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

    return completer.future;
  }

  /// Stop the module.
  Future<Null> stop() async {
    Completer<Null> completer = Completer<Null>();

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

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

    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.fine('terminate called');
    proxy.ctrl.close();
  }
}
