// Copyright 2019 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 'package:fuchsia_modular/agent.dart';
import 'package:fuchsia_logger/logger.dart';
import 'package:fidl/fidl.dart';
import 'package:fidl_fuchsia_modular_testing/fidl_async.dart';
import 'package:fidl_fuchsia_sys/fidl_async.dart' as fidl_sys;
import 'package:fuchsia_modular/src/agent/internal/_agent_impl.dart'; // ignore: implementation_imports
import 'package:fuchsia_services/src/internal/_startup_context_impl.dart'; // ignore: implementation_imports
import 'package:fuchsia_modular/src/lifecycle/internal/_lifecycle_impl.dart'; // ignore: implementation_imports

/// A function which is called when a new agent that is being launched.
typedef OnNewAgent = void Function(Agent agent);

/// A helper class for managing the intercepting of agents inside the
/// [TestHarness].
///
/// When agents which are registered to be mocked are launchedm the [OnNewAgent]
/// function will be executed allowing developers to expose services.
///
/// ```
/// AgentInterceptor(testHarness.onNewComponent)
///   .mockAgent(agentUrl, (agent) {
///     agent.exposeService(myService);
///   });
///
/// connectToAgentService(agentUrl, myServiceProxy,
///     componentContextProxy, await getComponentContext(harness));
/// ```
class AgentInterceptor {
  final _registeredAgents = <String, OnNewAgent>{};
  final _mockedAgents = <String, _MockedAgent>{};

  /// Creates an instance of this which will listen to the [onNewComponentStream].
  AgentInterceptor(
      Stream<TestHarness$OnNewComponent$Response> onNewComponentStream)
      : assert(onNewComponentStream != null) {
    onNewComponentStream.listen(_handleResponse);
  }

  /// Register an [agentUrl] to be mocked.
  ///
  /// If a component with the component url which matches [agentUrl] is
  /// registered to be interecepted by the test harness [onNewAgent] will be
  /// called when that component is first launched. The [onNewAgent] method will
  /// be called with an injected [Agent] object. This method can be treated like
  /// a normal main method in a non mocked agent.
  void mockAgent(String agentUrl, OnNewAgent onNewAgent) {
    ArgumentError.checkNotNull(agentUrl, 'agentUrl');
    ArgumentError.checkNotNull(onNewAgent, 'onNewAgent');

    if (agentUrl.isEmpty) {
      throw ArgumentError('agentUrl must not be empty');
    }

    if (_registeredAgents.containsKey(agentUrl)) {
      throw Exception(
          'Attempting to add [$agentUrl] twice. Agent urls must be unique');
    }
    _registeredAgents[agentUrl] = onNewAgent;
  }

  /// This method is called by the listen method when this object is used as the
  /// handler to the [TestHarnessProxy.onNewComponent] stream.
  void _handleResponse(TestHarness$OnNewComponent$Response response) {
    final startupInfo = response.startupInfo;
    final componentUrl = startupInfo.launchInfo.url;
    if (_registeredAgents.containsKey(componentUrl)) {
      final mockedAgent = _MockedAgent(
        startupInfo: startupInfo,
        interceptedComponentRequest: response.interceptedComponent,
      );
      _mockedAgents[componentUrl] = mockedAgent;
      _registeredAgents[componentUrl](mockedAgent.agent);
    } else {
      log.info(
          'Skipping launched component [$componentUrl] because it was not registered');
    }
  }
}

/// A helper class which helps manage the lifecyle of a mocked agent
class _MockedAgent {
  /// The intercepted component. This object can be used to control the
  /// launched component.
  final InterceptedComponentProxy interceptedComponent =
      InterceptedComponentProxy();

  /// The instance of the [Agent] which is running in this environment
  AgentImpl agent;

  /// The startup context for this environment
  StartupContextImpl context;

  /// The lifecycle service for this environment
  LifecycleImpl lifecycle;

  _MockedAgent({
    fidl_sys.StartupInfo startupInfo,
    InterfaceHandle<InterceptedComponent> interceptedComponentRequest,
  }) {
    context = StartupContextImpl.from(startupInfo);
    agent = AgentImpl(startupContext: context);
    lifecycle = LifecycleImpl(context: context)
      ..addTerminateListener(() async {
        interceptedComponent.ctrl.close();
      });

    interceptedComponent.ctrl.bind(interceptedComponentRequest);
  }
}
