// 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:typed_data';

import 'package:fidl/fidl.dart';
import 'package:fidl_fuchsia_mem/fidl_async.dart' as mem;
import 'package:fidl_fuchsia_modular/fidl_async.dart' as modular;
import 'package:fidl_fuchsia_ui_views/fidl_async.dart' as views;
import 'package:fidl_fuchsia_ui_viewsv1token/fidl_async.dart' as deprecated;
import 'package:fuchsia_modular/lifecycle.dart';
import 'package:meta/meta.dart';
import 'package:zircon/zircon.dart' as zx;

import '../../entity/entity.dart';
import '../../entity/internal/_entity_impl.dart';
import '../embedded_module.dart';
import '../intent.dart';
import '../intent_handler.dart';
import '../module.dart';
import '../module_state_exception.dart';
import '../ongoing_activity.dart';
import '_intent_handler_impl.dart';
import '_module_context.dart';
import '_ongoing_activity_impl.dart';

/// A concrete implementation of the [Module] interface. This class
/// is not intended to be used directly by authors but instead should
/// be used by the [Module] factory constructor.
class ModuleImpl implements Module {
  /// Holds a reference to the already registered intent handler
  IntentHandler _intentHandler;

  /// The intent handler host which will proxy intents to the registered
  /// intent handler
  // ignore: unused_field
  IntentHandlerImpl _intentHandlerImpl;

  /// Returns the [fidl.ModuleContext] for the running module.
  /// This variable should not be used directly. Use the
  /// [getContext()] method instead
  modular.ModuleContext _moduleContext;

  /// The default constructor for this instance.
  ///
  /// the [moduleContext] is an optional parameter that
  /// can be supplied to override the default module context.
  /// This is mainly useful in testing scenarios.
  ModuleImpl({
    @required IntentHandlerImpl intentHandlerImpl,
    Lifecycle lifecycle,
    modular.ModuleContext moduleContext,
  })  : _moduleContext = moduleContext,
        assert(intentHandlerImpl != null) {
    (lifecycle ??= Lifecycle()).addTerminateListener(_terminate);
    _intentHandlerImpl = intentHandlerImpl
      ..onHandleIntent = _proxyIntentToIntentHandler;
  }

  @override
  Future<modular.ModuleController> addModuleToStory({
    @required String name,
    @required modular.Intent intent,
    modular.SurfaceRelation surfaceRelation = const modular.SurfaceRelation(
      arrangement: modular.SurfaceArrangement.copresent,
      dependency: modular.SurfaceDependency.dependent,
      emphasis: 0.5,
    ),
  }) async {
    if (name == null || name.isEmpty) {
      throw ArgumentError.value(
          name, 'name', 'addModuleToStory should be called with a valid name');
    }
    if (intent == null) {
      throw ArgumentError.notNull('intent');
    }

    final moduleControllerProxy = modular.ModuleControllerProxy();

    modular.StartModuleStatus status = await _getContext().addModuleToStory(
        name, intent, moduleControllerProxy.ctrl.request(), surfaceRelation);

    _validateStartModuleStatus(status, name, intent);

    return moduleControllerProxy;
  }

  @override
  Future<Entity> createEntity({
    @required String type,
    @required Uint8List initialData,
  }) async {
    ArgumentError.checkNotNull(type, 'type');
    ArgumentError.checkNotNull(initialData, 'initialData');

    if (type.isEmpty) {
      throw ArgumentError.value(type, 'type cannot be an empty string');
    }

    final context = _getContext();

    // need to create the proxy and write data immediately so other modules
    // can extract values
    final proxy = modular.EntityProxy();
    final vmo = zx.SizedVmo.fromUint8List(initialData);
    final buffer = mem.Buffer(vmo: vmo, size: initialData.length);
    final ref = await context.createEntity(type, buffer, proxy.ctrl.request());

    // use the ref value to determine if creation was successful
    if (ref == null || ref.isEmpty) {
      throw Exception('Module.createEntity creation failed because'
          ' the framework was unable to create the entity.');
    }

    return EntityImpl(type: type, proxyFactory: () => proxy);
  }

  @override
  Future<EmbeddedModule> embedModule({
    @required String name,
    @required modular.Intent intent,
  }) async {
    return embedModuleNew(name: name, intent: intent);
  }

  @override
  Future<EmbeddedModule> embedModuleNew({
    @required String name,
    @required modular.Intent intent,
  }) async {
    if (name == null || name.isEmpty) {
      throw ArgumentError.value(
          name, 'name', 'embedModuleNew should be called with a valid name');
    }
    if (intent == null) {
      throw ArgumentError.notNull('intent');
    }

    final moduleController = modular.ModuleControllerProxy();
    final viewOwner = InterfacePair<deprecated.ViewOwner>();
    final status = await _getContext().embedModule(
        name, intent, moduleController.ctrl.request(), viewOwner.passRequest());

    _validateStartModuleStatus(status, name, intent);

    return EmbeddedModule(
        moduleController: moduleController,
        viewHolderToken: views.ViewHolderToken(
            value: zx.EventPair(
                viewOwner.passHandle().passChannel().passHandle())));
  }

  @override
  void registerIntentHandler(IntentHandler intentHandler) {
    if (_intentHandler != null) {
      throw ModuleStateException(
          'Intent handler registration failed because a handler is already '
          'registered.');
    }

    _intentHandler = intentHandler;
  }

  @override
  void removeSelfFromStory() {
    _getContext().removeSelfFromStory();
  }

  @override
  void requestFocus() {
    _getContext().requestFocus();
  }

  @override
  OngoingActivity startOngoingActivity(modular.OngoingActivityType type) {
    final proxy = modular.OngoingActivityProxy();
    _getContext().startOngoingActivity(type, proxy.ctrl.request());

    return OngoingActivityImpl(proxy);
  }

  modular.ModuleContext _getContext() => _moduleContext ??= getModuleContext();

  void _proxyIntentToIntentHandler(Intent intent) {
    if (_intentHandler == null) {
      throw ModuleStateException(
          'Module received an intent but no intent handler was registered to '
          'receive it. If you do not intend to handle intents but you still '
          'need to use the module functionality register a NoopIntentHandler '
          'to explicitly declare that you will not handle the intent.');
    }
    _intentHandler.handleIntent(intent);
  }

  // any necessary cleanup should be done in this method.
  Future<void> _terminate() async {
    _intentHandler = null;
  }

  void _validateStartModuleStatus(
      modular.StartModuleStatus status, String name, modular.Intent intent) {
    switch (status) {
      case modular.StartModuleStatus.success:
        break;
      case modular.StartModuleStatus.noModulesFound:
        throw ModuleResolutionException(
            'no modules found for intent [$intent]');
        break;
      default:
        throw ModuleStateException(
            'unknown start module status [$status] for intent [$intent]');
    }
  }
}

/// When Module resolution fails.
class ModuleResolutionException implements Exception {
  /// Information about the failure.
  final String message;

  /// Create a new [ModuleResolutionException].
  ModuleResolutionException(this.message);
}
