// 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 'dart:convert' show utf8, json;

import 'package:fidl_fuchsia_mem/fidl_async.dart' as fuchsia_mem;
import 'package:fidl_fuchsia_modular_testing/fidl_async.dart';
import 'package:zircon/zircon.dart';

/// A class which aids in the building of [TestHarnessSpec] objects.
///
/// This class is used to build up the spec and then pass that to the
/// run method of the test harness.
/// ```
/// final builder = TestHarnessBuilder()
///   ..addComponentToIntercept(componentUrl);
/// await harness.run(builder.build());
/// ```
class TestHarnessSpecBuilder {
  final _componentsToIntercept = <InterceptSpec>[];
  final _envServicesToInherit = <String>['fuchsia.logger.LogSink'];
  final _envServicesToInject = <InjectedService>[];

  /// Registers the component url to be intercepted.
  ///
  /// When a component with the given [componentUrl] is launched inside the
  /// hermetic environment it will not be launched by the system but rather
  /// passed to the [TestHarness]'s onNewComponent stream.
  ///
  /// Optionally, additional [services] can be provided which will be added
  /// to the intercepted components cmx file.
  void addComponentToIntercept(String componentUrl, {List<String> services}) {
    ArgumentError.checkNotNull(componentUrl, 'componentUrl');

    if (componentUrl.isEmpty) {
      throw ArgumentError('componentUrl must not be an empty string');
    }

    // verify that we have unique component urls
    for (final spec in _componentsToIntercept) {
      if (spec.componentUrl == componentUrl) {
        throw Exception(
            'Attempting to add [$componentUrl] twice. Component urls must be unique');
      }
    }

    final extraContents = <String, dynamic>{};
    if (services != null) {
      extraContents['services'] = services;
    }
    _componentsToIntercept.add(InterceptSpec(
        componentUrl: componentUrl,
        extraCmxContents: _createCmxSandBox(extraContents)));
  }

  /// Adds [service] to the list of services which should be inherited by the
  /// parent environment.
  ///
  /// The following environemnt services will be added by default. If you wish
  /// to not inherit these services you can remove them after building.
  ///  - fuchsia.logger.LogSink
  void addEnvironmentServiceToInherit(String service) {
    ArgumentError.checkNotNull(service, 'service');

    if (service.isEmpty) {
      throw ArgumentError('service must not be an empty string');
    }

    if (_envServicesToInherit.contains(service)) {
      throw Exception(
          'Attempting to add [$service] twice. Services must be unique');
    }

    _envServicesToInherit.add(service);
  }

  /// Adds the service with the given [name] and [componentUrl] to the list
  /// of services to inject.
  ///
  /// The [TestHarness] will automatically create these services and add
  /// expose them to the environment under test.
  void addEnvironmentServiceToInject(String name, String componentUrl) {
    ArgumentError.checkNotNull(name, 'name');
    ArgumentError.checkNotNull(componentUrl, 'componentUrl');

    if (name.isEmpty || componentUrl.isEmpty) {
      throw ArgumentError('name and componentUrl must not be an empty string');
    }

    final service = InjectedService(name: name, url: componentUrl);
    if (_envServicesToInject.contains(service)) {
      throw Exception(
          'Attempting to add [$service] twice. Services must be unique');
    }

    _envServicesToInject.add(service);
  }

  /// Returns the [TestHarnessSpec] object which can be passed to the [TestHarnessProxy]
  ///
  /// After building the [TestHarnessSpec] you may update its values directly if the builder
  /// does not offer a method which satisfies your specific needs.
  TestHarnessSpec build() {
    return TestHarnessSpec(
      componentsToIntercept: _componentsToIntercept,
      envServicesToInherit: _envServicesToInherit,
      envServicesToInject: _envServicesToInject,
    );
  }

  fuchsia_mem.Buffer _createCmxSandBox(Map<String, dynamic> contents) {
    if (contents.isEmpty) {
      return null;
    }
    final encodedContents = utf8.encode(json.encode({'sandbox': contents}));

    final vmo = SizedVmo.fromUint8List(encodedContents);
    return fuchsia_mem.Buffer(vmo: vmo, size: encodedContents.length);
  }
}
