// Copyright 2022 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 'dart:math';

import 'package:collection/collection.dart';
import 'package:fidl/fidl.dart' as fidl;
import 'package:fidl_fuchsia_component/fidl_async.dart' as fcomponent;
import 'package:fidl_fuchsia_component_config/fidl_async.dart' as fconfig;
import 'package:fidl_fuchsia_component_decl/fidl_async.dart' as fdecl;
import 'package:fidl_fuchsia_diagnostics_types/fidl_async.dart' as fdiagtypes;
import 'package:fidl_fuchsia_component_test/fidl_async.dart' as ftest;
import 'package:fidl_fuchsia_io/fidl_async.dart' as fio;

import 'package:fuchsia_logger/logger.dart';
import 'package:fuchsia_services/services.dart' as services;
import 'package:zircon/zircon.dart';

import 'error.dart';
import 'local_component_handles.dart';
import 'internal/local_component.dart';
import 'internal/local_component_runner.dart';

/// The default name of the child component collection that contains built
/// topologies.
const defaultCollectionName = 'realm_builder';

const realmBuilderServerChildName = 'realm_builder_server';

fconfig.ValueSpec _singleValue(fconfig.SingleValue value) {
  return fconfig.ValueSpec(value: fconfig.Value.withSingle(value));
}

fconfig.ValueSpec _vectorValue(fconfig.VectorValue value) {
  return fconfig.ValueSpec(value: fconfig.Value.withVector(value));
}

/// The properties for a child being added to a realm
class ChildOptions {
  fdecl.StartupMode _startup;
  String? environment;
  fdecl.OnTerminate _onTerminate;

  ChildOptions()
      : _startup = fdecl.StartupMode.lazy,
        _onTerminate = fdecl.OnTerminate.none;

  fdecl.StartupMode get startup => _startup;

  void eager() {
    _startup = fdecl.StartupMode.eager;
  }

  fdecl.OnTerminate get onTerminate => _onTerminate;

  void rebootOnTerminate() {
    _onTerminate = fdecl.OnTerminate.reboot;
  }

  /// Convert the current value into the FIDL table-backed ChildOptions, via its
  /// `const` constructor.
  ftest.ChildOptions toFidlType() {
    return ftest.ChildOptions(
      startup: _startup,
      environment: environment,
      onTerminate: _onTerminate,
    );
  }

  @override
  String toString() {
    return 'ChildOptions(startup = $_startup, environment = $environment, '
        'onTerminate = $onTerminate)';
  }
}

/// Provides convenience functions for using the instance. Components v2 only.
class ScopedInstanceFactory {
  fcomponent.RealmProxy? realmProxy;
  final String _collectionName;

  ScopedInstanceFactory(this._collectionName);

  String get collectionName => _collectionName;

  Future<ScopedInstance> newInstance(String url) {
    final id = Random().nextInt(1 << 32);
    final childName = 'auto-${id.toRadixString(16)}';
    return newNamedInstance(childName, url);
  }

  Future<ScopedInstance> newNamedInstance(String childName, String url) async {
    late final fcomponent.RealmProxy realmProxy;
    if (this.realmProxy != null) {
      realmProxy = this.realmProxy!;
    } else {
      realmProxy = fcomponent.RealmProxy();
      await (services.Incoming.fromSvcPath()..connectToService(realmProxy))
          .close();
    }

    final collectionRef = fdecl.CollectionRef(name: _collectionName);
    final childDecl = fdecl.Child(
      name: childName,
      url: url,
      startup: fdecl.StartupMode.lazy,
    );
    final childArgs = fcomponent.CreateChildArgs();

    await realmProxy.createChild(
      collectionRef,
      childDecl,
      childArgs,
    );

    final childRef = fdecl.ChildRef(
      name: childName,
      collection: _collectionName,
    );

    final exposedDir = fio.DirectoryProxy();
    await realmProxy.openExposedDir(
      childRef,
      exposedDir.ctrl.request(),
    );

    return ScopedInstance._(
      realmProxy,
      childName,
      _collectionName,
      exposedDir,
    );
  }
}

/// Provides convenience functions for using the instance. Components v2 only.
class ScopedInstance {
  final fcomponent.RealmProxy _realm;
  final String _childName;
  final String _collectionName;
  final fio.DirectoryProxy _exposedDir;

  const ScopedInstance._(
    this._realm,
    this._childName,
    this._collectionName,
    this._exposedDir,
  );

  static Future<ScopedInstance> create({
    required String collectionName,
    required String url,
    String? childName,
  }) {
    final factory = ScopedInstanceFactory(collectionName);
    if (childName == null) {
      return factory.newInstance(url);
    } else {
      return factory.newNamedInstance(childName, url);
    }
  }

  /// Returns a reference to the component's read-only exposed directory.
  fio.DirectoryProxy get exposedDir => _exposedDir;

  String get childName => _childName;
  String get collectionName => _collectionName;

  /// Connect to exposed fuchsia.component.Binder protocol of instance, thus
  /// triggering it to start.
  ///
  /// Note: This will only work if the component exposes this protocol in its
  /// manifest.
  fcomponent.BinderProxy connectToBinder() {
    try {
      return connectToProtocolAtExposedDir(fcomponent.BinderProxy());
    } on Exception catch (err) {
      log.severe('failed to connect to fuchsia.component.Binder: $err');
      rethrow;
    }
  }

  /// Connect to an instance of a FIDL protocol hosted in the component's
  /// exposed directory, based on the type of the given proxy. The given
  /// proxy is returned.
  T connectToProtocolAtExposedDir<T extends fidl.AsyncProxy>(T proxy) {
    services.Incoming.withDirectory(exposedDir).connectToService(proxy);
    return proxy;
  }

  /// Connects to an instance of a FIDL protocol hosted in the component's
  /// exposed directory using the given [serverEnd]. Any proxy of the same
  /// protocol type is also required, in order to get the protocol name.
  void connectRequestToProtocolAtExposedDir<P>(
      fidl.InterfaceRequest<P> serverEnd, fidl.AsyncProxy<P> anyProxy) {
    final ctrl = anyProxy.ctrl;
    final protocolName = ctrl.$serviceName ?? ctrl.$interfaceName!;
    connectToNamedProtocolAtExposedDir(protocolName, serverEnd.passChannel()!);
  }

  /// Connects to an instance of a FIDL protocol called [protocolName] hosted in
  /// the component's exposed directory, using the given [serverEnd].
  void connectToNamedProtocolAtExposedDir(
      String protocolName, Channel serverEnd) {
    services.Incoming.withDirectory(exposedDir)
        .connectToServiceByNameWithChannel(protocolName, serverEnd);
  }

  /// Connects to an instance of a FIDL protocol called [protocolName] hosted at
  /// the absolute path from the exposed directory.
  T connectToProtocolAtPath<T extends fidl.AsyncProxy>(
      T proxy, String protocolPath) {
    var serverEnd = proxy.ctrl.request().passChannel();
    exposedDir.open(
      fio.OpenFlags.rightReadable | fio.OpenFlags.rightWritable,
      fio.modeTypeService,
      protocolPath,
      fidl.InterfaceRequest<fio.Node>(serverEnd),
    );
    return proxy;
  }

  /// Connects to an instance of a FIDL protocol hosted at the protocol name,
  /// in the given directory.
  T connectToProtocolInDirPath<T extends fidl.AsyncProxy>(
    T proxy,
    String dirPath,
  ) {
    return connectToProtocolAtPath(
      proxy,
      '$dirPath/${proxy.ctrl.$serviceName}',
    );
  }

  /// Call [close()] before the [ScopedInstance] goes out of scope (since
  /// Dart doesn't support destructors or RAII destruction when an object
  /// goes out of scope).
  ///
  /// This will ensure that the message goes out to the realm.
  ///
  /// Note: `destroyChild()`s returned Future may not complete immediately.
  /// The process of destroying a component and its children includes various
  /// confirmations, with time-outs in case a component doesn't stop cleanly.
  /// This `close()` method sends the `destroyChild()` request and returns
  /// without waiting for confirmation. It returns `void` instead of the
  /// [Future] so callers are discouraged from awaiting the close(), which can
  /// be the source of non-deterministic delays and/or timeouts.
  void close() {
    _realm.destroyChild(fdecl.ChildRef(
      name: childName,
      collection: collectionName,
    ));
  }
}

enum RefType {
  capability,
  child,
  collection,
  debug,
  framework,
  parent,
  self,
}

extension RefEnumToName on RefType {
  String enumName() {
    final segments = toString().split('.');
    return segments.isEmpty ? '' : segments.last;
  }
}

class Ref {
  final RefType type;

  String? name;

  List<String>? scope;

  Ref.from(Ref o)
      : type = o.type,
        name = o.name,
        scope = o.scope?.toList();

  Ref.capability(this.name) : type = RefType.capability;
  Ref.collection(this.name) : type = RefType.collection;
  Ref.debug() : type = RefType.debug;
  Ref.framework() : type = RefType.framework;
  Ref.parent() : type = RefType.parent;
  Ref.self() : type = RefType.self;

  Ref.child(ChildRef childRef)
      : type = RefType.child,
        name = childRef.name,
        scope = childRef.scope;

  Ref.childFromSubRealm(SubRealmBuilder subRealm)
      : type = RefType.child,
        name = subRealm.realmPath.isEmpty ? null : subRealm.realmPath.last,
        scope = subRealm.realmPath.toList()..removeLast() {
    if (name == null) {
      throw Exception(
          'API bug: It should not be possible to call fromSubRealmBuilder '
          'with a top-level SubRealmBuilder');
    }
  }

  void checkScope(List<String> realmScope) {
    if (scope != null && !ListEquality().equals(scope, realmScope)) {
      throw RefUsedInWrongRealmException(this, realmScope.join('/'));
    }
  }

  @override
  bool operator ==(Object o) =>
      o is Ref &&
      type == o.type &&
      name == o.name &&
      ListEquality().equals(scope, o.scope);

  @override
  int get hashCode => type.hashCode + name.hashCode + scope.hashCode;

  /// Convert the current value into the FIDL table-backed ChildOptions, via its
  /// `const` constructor.
  fdecl.Ref toFidlType() {
    switch (type) {
      case RefType.capability:
        return fdecl.Ref.withCapability(fdecl.CapabilityRef(name: name!));
      case RefType.child:
        return fdecl.Ref.withChild(fdecl.ChildRef(name: name!));
      case RefType.collection:
        return fdecl.Ref.withCollection(fdecl.CollectionRef(name: name!));
      case RefType.debug:
        return fdecl.Ref.withDebug(fdecl.DebugRef());
      case RefType.framework:
        return fdecl.Ref.withFramework(fdecl.FrameworkRef());
      case RefType.parent:
        return fdecl.Ref.withParent(fdecl.ParentRef());
      case RefType.self:
        return fdecl.Ref.withSelf(fdecl.SelfRef());
    }
  }

  @override
  String toString() {
    return '${type.enumName()} Ref(name=${name == null ? 'null' : '"$name"'}, '
        'scope=$scope)';
  }
}

class ChildRef {
  String name;
  List<String>? scope;

  ChildRef(this.name, [this.scope]);

  void checkScope(List<String> realmScope) {
    if (scope != null && !ListEquality().equals(scope, realmScope)) {
      throw RefUsedInWrongRealmException(
        Ref.child(this),
        realmScope.join('/'),
      );
    }
  }

  ChildRef.fromSubRealmBuilder(SubRealmBuilder input)
      : name = input.realmPath.isEmpty ? '' : input.realmPath.last,
        scope = input.realmPath.toList()..removeLast() {
    if (name == '') {
      throw Exception(
          'API bug: It should not be possible to call fromSubRealmBuilder '
          'with a top-level SubRealmBuilder');
    }
  }

  ChildRef.fromChildRef(ChildRef input)
      : name = input.name,
        scope = input.scope?.toList();

  @override
  String toString() {
    return 'ChildRef(name = $name, scope = $scope)';
  }
}

extension DependencyTypeEnumToName on fdecl.DependencyType {
  String enumName() {
    final segments = toString().split('.');
    return segments.isEmpty ? '' : segments.last;
  }
}

abstract class Capability {
  String name;

  /// The name the targets will see the capability as.
  String? as;

  Capability(this.name, [this.as]);

  ftest.Capability toFidlType();

  String _capabilityToString(String? additionalFields) {
    return '$runtimeType(name = $name, '
        'as = $as${additionalFields != null ? ', $additionalFields' : ''})';
  }
}

/// A protocol capability, which may be routed between components. Created by
/// [Capability.protocol()].
class ProtocolCapability extends Capability {
  fdecl.DependencyType type;

  /// The path at which this protocol capability will be provided or used. Only
  /// relevant if the route's source or target is a legacy or local component,
  /// as these are the only components that realm builder will generate a modern
  /// component manifest for.
  String? path;

  ProtocolCapability(
    name, {
    as,
    this.type = fdecl.DependencyType.strong,
    this.path,
  }) : super(name, as);

  ProtocolCapability.from(ProtocolCapability o)
      : type = o.type,
        path = o.path,
        super(o.name, o.as);

  /// Marks any offers involved in this route as "weak", which will cause this
  /// route to be ignored when determining shutdown ordering.
  void weak() {
    type = fdecl.DependencyType.weak;
  }

  @override
  ftest.Capability toFidlType() {
    return ftest.Capability.withProtocol(ftest.Protocol(
      name: name,
      as: as,
      type: type,
      path: path,
    ));
  }

  @override
  bool operator ==(Object o) =>
      o is ProtocolCapability &&
      name == o.name &&
      as == o.as &&
      type == o.type &&
      path == o.path;

  @override
  int get hashCode =>
      name.hashCode + as.hashCode + type.hashCode + path.hashCode;

  @override
  String toString() {
    return _capabilityToString('type = ${type.enumName()}, path = $path');
  }
}

/// A directory capability, which may be routed between components. Created by
/// [Capability.directory()].
class DirectoryCapability extends Capability {
  fdecl.DependencyType type;

  /// The rights the target will be allowed to use when accessing the directory.
  fio.Operations? rights;

  /// The sub-directory of the directory that the target will be given access
  /// to.
  String? subdir;

  /// The path at which this directory will be provided or used. Only relevant
  /// if the route's source or target is a local component.
  String? path;

  DirectoryCapability(
    name, {
    as,
    this.type = fdecl.DependencyType.strong,
    this.rights,
    this.subdir,
    this.path,
  }) : super(name, as);

  DirectoryCapability.from(DirectoryCapability o)
      : type = o.type,
        path = o.path,
        super(o.name, o.as);

  /// Marks any offers involved in this route as "weak", which will cause this
  /// route to be ignored when determining shutdown ordering.
  void weak() {
    type = fdecl.DependencyType.weak;
  }

  @override
  ftest.Capability toFidlType() {
    return ftest.Capability.withDirectory(ftest.Directory(
      name: name,
      as: as,
      type: type,
      rights: rights,
      subdir: subdir,
      path: path,
    ));
  }

  @override
  bool operator ==(Object o) =>
      o is DirectoryCapability &&
      name == o.name &&
      as == o.as &&
      type == o.type &&
      rights == o.rights &&
      subdir == o.subdir &&
      path == o.path;

  @override
  int get hashCode =>
      name.hashCode +
      as.hashCode +
      type.hashCode +
      rights.hashCode +
      subdir.hashCode +
      path.hashCode;

  @override
  String toString() {
    return _capabilityToString(
        'type = ${type.enumName()}, rights = $rights, subdir = $subdir, '
        'path = $path');
  }
}

/// A storage capability, which may be routed between components. Created by
/// [Capability.storage()].
class StorageCapability extends Capability {
  /// The path at which this storage capability will be provided or used. Only
  /// relevant if the route's source or target is a legacy or local component,
  /// as these are the only components that realm builder will generate a modern
  /// component manifest for.
  String? path;

  StorageCapability(name, {as, this.path}) : super(name, as);

  StorageCapability.from(StorageCapability o)
      : path = o.path,
        super(o.name, o.as);

  @override
  ftest.Capability toFidlType() {
    return ftest.Capability.withStorage(
        ftest.Storage(name: name, as: as, path: path));
  }

  @override
  bool operator ==(Object o) =>
      o is StorageCapability && name == o.name && as == o.as && path == o.path;

  @override
  int get hashCode => name.hashCode + as.hashCode + path.hashCode;

  @override
  String toString() {
    return _capabilityToString('path = $path');
  }
}

/// A service capability, which may be routed between components. Created by
/// [Capability.service()].
class ServiceCapability extends Capability {
  /// The path at which this service capability will be provided or used. Only
  /// relevant if the route's source or target is a legacy or local component,
  /// as these are the only components that realm builder will generate a modern
  /// component manifest for.
  String? path;

  ServiceCapability(
    name, {
    as,
    this.path,
  }) : super(name, as);

  ServiceCapability.from(ServiceCapability o)
      : path = o.path,
        super(o.name, o.as);

  @override
  ftest.Capability toFidlType() {
    return ftest.Capability.withService(ftest.Service(
      name: name,
      as: as,
      path: path,
    ));
  }

  @override
  bool operator ==(Object o) =>
      o is ServiceCapability && name == o.name && as == o.as && path == o.path;

  @override
  int get hashCode => name.hashCode + as.hashCode + path.hashCode;

  @override
  String toString() {
    return _capabilityToString('path = $path');
  }
}

/// A route of one or more capabilities from one point in the realm to one or
/// more targets.
class Route {
  final List<Capability> _capabilities;
  Ref? _from;
  final List<Ref> _to;

  Route()
      : _capabilities = [],
        _to = [];

  Route.from(Route o)
      : _capabilities = o._capabilities.toList(),
        _from = o._from,
        _to = o._to.toList();

  List<Capability> getCapabilities() => _capabilities;
  Ref? getFrom() => _from;
  List<Ref> getTo() => _to;

  void capability(Capability capability) {
    _capabilities.add(capability);
  }

  /// Adds a source to this route. Must be called exactly once. Will panic if
  /// called a second time.
  void from(Ref from) {
    if (_from != null) {
      throw Exception('from is already set for this route');
    }
    _from = from;
  }

  void to(Ref to) {
    _to.add(to);
  }

  @override
  bool operator ==(Object o) =>
      o is Route &&
      ListEquality().equals(_capabilities, o._capabilities) &&
      _from == o._from &&
      ListEquality().equals(_to, o._to);

  @override
  int get hashCode => _capabilities.hashCode + _from.hashCode + _to.hashCode;
}

// [START mock_interface_dart]
typedef OnRun = Future<void> Function(
  LocalComponentHandles handles,
  Completer onStop,
);
// [END mock_interface_dart]
typedef OnKill = Future<void> Function(LocalComponentHandles handles);
typedef OnOnPublishDiagnostics = Stream<fdiagtypes.ComponentDiagnostics>
    Function(LocalComponentHandles handles);
typedef OnStop = Future<void> Function(LocalComponentHandles handles);

/// A running instance of a created realm. Important: When a RealmInstance is no
/// longer needed, the root [ScopedInstance] must be closed--by calling
/// root.close()--to ensure the child component is not leaked. When closed, the
/// realm is destroyed, along with any components that were in the realm.
class RealmInstance {
  /// The root component of this realm instance, which can be used to access
  /// exposed capabilities from the realm.
  final ScopedInstance root;

  const RealmInstance(this.root);
}

class SubRealmBuilder {
  ftest.RealmProxy realmProxy;
  List<String> realmPath;

  // Required for builder API but not yet implemented or used.
  final _localComponentRunnerBuilder = LocalComponentRunnerBuilder();

  SubRealmBuilder({
    required this.realmProxy,
    required this.realmPath,
  });

  /// Adds a child realm and returns a [SubRealmBuilder]. Capabilities can be
  /// routed between parent [RealmBuilder] and the sub-realm, and then routed
  /// to/from children of the sub-realm.
  Future<SubRealmBuilder> addChildRealm(String name,
      [ChildOptions? options]) async {
    final childRealm = ftest.RealmProxy();
    await realmProxy.addChildRealm(
      name,
      (options ?? ChildOptions()).toFidlType(),
      childRealm.ctrl.request(),
    );
    final childPath = realmPath.toList()..add(name);
    return SubRealmBuilder(
      realmProxy: childRealm,
      realmPath: childPath,
    );
  }

  /// Adds a local component to the realm. the [onRun] callback will be called
  /// when the component starts. Other [ComponentController] callbacks are
  /// optional.
  ///
  /// The [ComponentController] binding must be closed to indicate to Component
  /// Manager that the [LocalComponent] has stopped. If [onStop] is not
  /// provided, the default implementation will automatically close the
  /// [ComponentController] binding. If [onRun] completes before [onStop] (if
  /// called) the [ComponentController] binding will be closed automatically. If
  /// [onStop] is provided, the caller can close the [ComponentController]
  /// binding by calling [LocalComponentHandles.close()].
  ///
  /// [onRun] is given the [LocalComponentHandles] (to access its namespace,
  /// outgoing directory, and [ComponentController]), and a [Completer] that
  /// is completed if [ComponentController.stop()] is called. The caller can
  /// await the `onStopCompleter` allow the component to continue to remain
  /// active until the `stop()` is received.
  Future<ChildRef> addLocalChild(
    String name, {
    required OnRun onRun,
    OnKill? onKill,
    OnOnPublishDiagnostics? onOnPublishDiagnostics,
    OnStop? onStop,
    ChildOptions? options,
  }) async {
    await realmProxy.addLocalChild(
      name,
      (options ?? ChildOptions()).toFidlType(),
    );
    final childPath = realmPath + [name];
    _localComponentRunnerBuilder.registerLocalComponent(
      LocalComponent(
        childPath.join('/'),
        onRun,
        onKill,
        onOnPublishDiagnostics,
        onStop,
      ),
    );
    return ChildRef(name, realmPath);
  }

  /// Adds a new component to the realm by URL.
  Future<ChildRef> addChild(String name, String url,
      [ChildOptions? options]) async {
    await realmProxy.addChild(
      name,
      url,
      (options ?? ChildOptions()).toFidlType(),
    );
    return ChildRef(name, realmPath);
  }

  /// Adds a new legacy component to the realm.
  Future<ChildRef> addLegacyChild(String name, String legacyUrl,
      [ChildOptions? options]) async {
    await realmProxy.addLegacyChild(
      name,
      legacyUrl,
      (options ?? ChildOptions()).toFidlType(),
    );
    return ChildRef(name, realmPath);
  }

  /// Adds a new component to the realm with the given component declaration
  Future<ChildRef> addChildFromDecl(String name, fdecl.Component decl,
      [ChildOptions? options]) async {
    await realmProxy.addChildFromDecl(
      name,
      decl,
      (options ?? ChildOptions()).toFidlType(),
    );
    return ChildRef(name, realmPath);
  }

  /// Returns a copy the decl for a child in this realm
  Future<fdecl.Component> getComponentDecl(ChildRef childRef) {
    childRef.checkScope(realmPath);
    return realmProxy.getComponentDecl(childRef.name);
  }

  /// Replaces the decl for a child of this realm
  Future<void> replaceComponentDecl(
    ChildRef childRef,
    fdecl.Component decl,
  ) {
    childRef.checkScope(realmPath);
    return realmProxy.replaceComponentDecl(childRef.name, decl);
  }

  /// Returns a copy the decl for a child in this realm
  Future<fdecl.Component> getRealmDecl() {
    return realmProxy.getRealmDecl();
  }

  /// Replaces the decl for this realm
  Future<void> replaceRealmDecl(fdecl.Component decl) {
    return realmProxy.replaceRealmDecl(decl);
  }

  /// Replaces a value of a given configuration field
  Future<void> setConfigValue(
    ChildRef childRef,
    String key,
    fconfig.ValueSpec value,
  ) {
    childRef.checkScope(realmPath);
    return realmProxy.setConfigValue(childRef.name, key, value);
  }

  /// Replaces a boolean value of a given configuration field
  Future<void> setConfigValueBool(
    ChildRef childRef,
    String key,
    // ignore: avoid_positional_boolean_parameters
    bool value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _singleValue(fconfig.SingleValue.withBool(value)),
    );
  }

  /// Replaces a uint8 value of a given configuration field
  Future<void> setConfigValueUint8(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _singleValue(fconfig.SingleValue.withUint8(value)),
    );
  }

  /// Replaces a uint16 value of a given configuration field
  Future<void> setConfigValueUint16(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _singleValue(fconfig.SingleValue.withUint16(value)),
    );
  }

  /// Replaces a uint32 value of a given configuration field
  Future<void> setConfigValueUint32(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _singleValue(fconfig.SingleValue.withUint32(value)),
    );
  }

  /// Replaces a uint64 value of a given configuration field
  Future<void> setConfigValueUint64(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _singleValue(fconfig.SingleValue.withUint64(value)),
    );
  }

  /// Replaces a int8 value of a given configuration field
  Future<void> setConfigValueInt8(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _singleValue(fconfig.SingleValue.withInt8(value)),
    );
  }

  /// Replaces a int16 value of a given configuration field
  Future<void> setConfigValueInt16(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _singleValue(fconfig.SingleValue.withInt16(value)),
    );
  }

  /// Replaces a int32 value of a given configuration field
  Future<void> setConfigValueInt32(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _singleValue(fconfig.SingleValue.withInt32(value)),
    );
  }

  /// Replaces a int64 value of a given configuration field
  Future<void> setConfigValueInt64(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _singleValue(fconfig.SingleValue.withInt64(value)),
    );
  }

  /// Replaces a string value of a given configuration field
  Future<void> setConfigValueString(
    ChildRef childRef,
    String key,
    String value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _singleValue(fconfig.SingleValue.withString$(value)),
    );
  }

  /// Replaces a boolean vector value of a given configuration field
  Future<void> setConfigValueBoolVector(
    ChildRef childRef,
    String key,
    List<bool> value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _vectorValue(fconfig.VectorValue.withBoolVector(value)),
    );
  }

  /// Replaces a uint8 vector value of a given configuration field
  Future<void> setConfigValueUint8Vector(
    ChildRef childRef,
    String key,
    Uint8List value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _vectorValue(fconfig.VectorValue.withUint8Vector(value)),
    );
  }

  /// Replaces a uint16 vector value of a given configuration field
  Future<void> setConfigValueUint16Vector(
    ChildRef childRef,
    String key,
    Uint16List value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _vectorValue(fconfig.VectorValue.withUint16Vector(value)),
    );
  }

  /// Replaces a uint32 vector value of a given configuration field
  Future<void> setConfigValueUint32Vector(
    ChildRef childRef,
    String key,
    Uint32List value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _vectorValue(fconfig.VectorValue.withUint32Vector(value)),
    );
  }

  /// Replaces a uint64 vector value of a given configuration field
  Future<void> setConfigValueUint64Vector(
    ChildRef childRef,
    String key,
    Uint64List value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _vectorValue(fconfig.VectorValue.withUint64Vector(value)),
    );
  }

  /// Replaces a int8 vector value of a given configuration field
  Future<void> setConfigValueInt8Vector(
    ChildRef childRef,
    String key,
    Int8List value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _vectorValue(fconfig.VectorValue.withInt8Vector(value)),
    );
  }

  /// Replaces a int16 vector value of a given configuration field
  Future<void> setConfigValueInt16Vector(
    ChildRef childRef,
    String key,
    Int16List value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _vectorValue(fconfig.VectorValue.withInt16Vector(value)),
    );
  }

  /// Replaces a int32 vector value of a given configuration field
  Future<void> setConfigValueInt32Vector(
    ChildRef childRef,
    String key,
    Int32List value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _vectorValue(fconfig.VectorValue.withInt32Vector(value)),
    );
  }

  /// Replaces a int64 vector value of a given configuration field
  Future<void> setConfigValueInt64Vector(
    ChildRef childRef,
    String key,
    Int64List value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _vectorValue(fconfig.VectorValue.withInt64Vector(value)),
    );
  }

  /// Replaces a string vector value of a given configuration field
  Future<void> setConfigValueStringVector(
    ChildRef childRef,
    String key,
    List<String> value,
  ) {
    return setConfigValue(
      childRef,
      key,
      _vectorValue(fconfig.VectorValue.withStringVector(value)),
    );
  }

  /// Adds a route between components within the realm
  Future<void> addRoute(Route route) async {
    final capabilities = route.getCapabilities();
    final from = route.getFrom();
    final to = route.getTo();
    if (from == null) {
      throw MissingSource();
    }
    final source = from..checkScope(realmPath);
    for (final target in to) {
      target.checkScope(realmPath);
    }
    if (capabilities.isNotEmpty) {
      await realmProxy.addRoute(
        capabilities.map((c) => c.toFidlType()).toList(),
        source.toFidlType(),
        to.map((Ref ref) => ref.toFidlType()).toList(),
      );
    }
  }
}

/// A class that aids in the building of [RealmBuilder] objects.
///
/// This class is used to create Fuchsia component tests in Dart, using the
/// RealmBuilder framework.
///
/// ```
/// final builder = RealmBuilder();
/// builder.addChild(...);
/// builder.addRoute(...);
/// realmInstance = await builder.build();
/// realmInstance.root.connectToProtocol...
/// ```
class RealmBuilder {
  late final SubRealmBuilder _rootRealm;

  late final ftest.BuilderProxy _builder;

  /// The realm will be launched in the collection named [collectionName].
  final String collectionName;

  /// Creates a new RealmBuilder.
  /// [relativeUrl]: The path to a manifest to load into the realm.
  /// [collectionName]: The collection to add the realm to, when launched.
  static Future<RealmBuilder> create({
    String? relativeUrl,
    String collectionName = defaultCollectionName,
  }) async {
    final componentRealm = fcomponent.RealmProxy();
    await (services.Incoming.fromSvcPath()..connectToService(componentRealm))
        .close();

    final exposedDir = fio.DirectoryProxy();
    await componentRealm.openExposedDir(
      fdecl.ChildRef(name: realmBuilderServerChildName),
      exposedDir.ctrl.request(),
    );

    final realmBuilderFactory = ftest.RealmBuilderFactoryProxy();
    await (services.Incoming.withDirectory(exposedDir)
          ..connectToService(realmBuilderFactory))
        .close();

    final pkgDirHandle =
        fidl.InterfaceHandle<fio.Directory>(Channel.fromFile('/pkg'));

    final realm = ftest.RealmProxy();
    final builder = ftest.BuilderProxy();
    if (relativeUrl == null) {
      await realmBuilderFactory.create(
        pkgDirHandle,
        realm.ctrl.request(),
        builder.ctrl.request(),
      );
    } else {
      // load the manifest
      await realmBuilderFactory.createFromRelativeUrl(
        pkgDirHandle,
        relativeUrl,
        realm.ctrl.request(),
        builder.ctrl.request(),
      );
    }
    return RealmBuilder._(realm, builder, collectionName);
  }

  RealmBuilder._(
    ftest.RealmProxy realmProxy,
    this._builder,
    this.collectionName,
  ) {
    _rootRealm = SubRealmBuilder(realmProxy: realmProxy, realmPath: []);
  }

  SubRealmBuilder get rootRealm => _rootRealm;

  ftest.BuilderProxy get builder => _builder;

  /// Adds a child realm and returns a [SubRealmBuilder]. Capabilities can be
  /// routed between parent [RealmBuilder] and the sub-realm, and then routed
  /// to/from children of the sub-realm.
  Future<SubRealmBuilder> addChildRealm(String name, [ChildOptions? options]) {
    return rootRealm.addChildRealm(
      name,
      options ?? ChildOptions(),
    );
  }

  /// Adds a new component to the realm by URL.
  Future<ChildRef> addLocalChild(
    String name, {
    required OnRun onRun,
    OnKill? onKill,
    OnOnPublishDiagnostics? onOnPublishDiagnostics,
    OnStop? onStop,
    ChildOptions? options,
  }) {
    return rootRealm.addLocalChild(
      name,
      onRun: onRun,
      onKill: onKill,
      onOnPublishDiagnostics: onOnPublishDiagnostics,
      onStop: onStop,
      options: options ?? ChildOptions(),
    );
  }

  /// Adds a new component to the realm by URL.
  Future<ChildRef> addChild(String name, String url, [ChildOptions? options]) {
    return rootRealm.addChild(
      name,
      url,
      options ?? ChildOptions(),
    );
  }

  /// Adds a new legacy component to the realm.
  Future<ChildRef> addLegacyChild(String name, String legacyUrl,
      [ChildOptions? options]) {
    return rootRealm.addLegacyChild(
      name,
      legacyUrl,
      options ?? ChildOptions(),
    );
  }

  /// Adds a new component to the realm with the given component declaration
  Future<ChildRef> addChildFromDecl(String name, fdecl.Component decl,
      [ChildOptions? options]) {
    return rootRealm.addChildFromDecl(
      name,
      decl,
      options ?? ChildOptions(),
    );
  }

  /// Returns a copy the decl for a child in this realm
  Future<fdecl.Component> getComponentDecl(ChildRef childRef) {
    return rootRealm.getComponentDecl(childRef);
  }

  /// Replaces the decl for a child of this realm
  Future<void> replaceComponentDecl(
    ChildRef childRef,
    fdecl.Component decl,
  ) {
    return rootRealm.replaceComponentDecl(childRef, decl);
  }

  /// Returns a copy the decl for a child in this realm
  Future<fdecl.Component> getRealmDecl() {
    return rootRealm.getRealmDecl();
  }

  /// Replaces the decl for this realm
  Future<void> replaceRealmDecl(
    fdecl.Component decl,
  ) {
    return rootRealm.replaceRealmDecl(decl);
  }

  /// Replaces a value of a given configuration field
  Future<void> setConfigValue(
    ChildRef childRef,
    String key,
    fconfig.ValueSpec value,
  ) {
    return rootRealm.setConfigValue(childRef, key, value);
  }

  /// Replaces a boolean value of a given configuration field
  Future<void> setConfigValueBool(
    ChildRef childRef,
    String key,
    // ignore: avoid_positional_boolean_parameters
    bool value,
  ) {
    return rootRealm.setConfigValueBool(childRef, key, value);
  }

  /// Replaces a uint8 value of a given configuration field
  Future<void> setConfigValueUint8(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return rootRealm.setConfigValueUint8(childRef, key, value);
  }

  /// Replaces a uint16 value of a given configuration field
  Future<void> setConfigValueUint16(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return rootRealm.setConfigValueUint16(childRef, key, value);
  }

  /// Replaces a uint32 value of a given configuration field
  Future<void> setConfigValueUint32(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return rootRealm.setConfigValueUint32(childRef, key, value);
  }

  /// Replaces a uint64 value of a given configuration field
  Future<void> setConfigValueUint64(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return rootRealm.setConfigValueUint64(childRef, key, value);
  }

  /// Replaces a int8 value of a given configuration field
  Future<void> setConfigValueInt8(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return rootRealm.setConfigValueInt8(childRef, key, value);
  }

  /// Replaces a int16 value of a given configuration field
  Future<void> setConfigValueInt16(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return rootRealm.setConfigValueInt16(childRef, key, value);
  }

  /// Replaces a int32 value of a given configuration field
  Future<void> setConfigValueInt32(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return rootRealm.setConfigValueInt32(childRef, key, value);
  }

  /// Replaces a int64 value of a given configuration field
  Future<void> setConfigValueInt64(
    ChildRef childRef,
    String key,
    int value,
  ) {
    return rootRealm.setConfigValueInt64(childRef, key, value);
  }

  /// Replaces a string value of a given configuration field
  Future<void> setConfigValueString(
    ChildRef childRef,
    String key,
    String value,
  ) {
    return rootRealm.setConfigValueString(childRef, key, value);
  }

  /// Replaces a boolean vector value of a given configuration field
  Future<void> setConfigValueBoolVector(
    ChildRef childRef,
    String key,
    List<bool> value,
  ) {
    return rootRealm.setConfigValueBoolVector(childRef, key, value);
  }

  /// Replaces a uint8 vector value of a given configuration field
  Future<void> setConfigValueUint8Vector(
    ChildRef childRef,
    String key,
    Uint8List value,
  ) {
    return rootRealm.setConfigValueUint8Vector(childRef, key, value);
  }

  /// Replaces a uint16 vector value of a given configuration field
  Future<void> setConfigValueUint16Vector(
    ChildRef childRef,
    String key,
    Uint16List value,
  ) {
    return rootRealm.setConfigValueUint16Vector(childRef, key, value);
  }

  /// Replaces a uint32 vector value of a given configuration field
  Future<void> setConfigValueUint32Vector(
    ChildRef childRef,
    String key,
    Uint32List value,
  ) {
    return rootRealm.setConfigValueUint32Vector(childRef, key, value);
  }

  /// Replaces a uint64 vector value of a given configuration field
  Future<void> setConfigValueUint64Vector(
    ChildRef childRef,
    String key,
    Uint64List value,
  ) {
    return rootRealm.setConfigValueUint64Vector(childRef, key, value);
  }

  /// Replaces a int8 vector value of a given configuration field
  Future<void> setConfigValueInt8Vector(
    ChildRef childRef,
    String key,
    Int8List value,
  ) {
    return rootRealm.setConfigValueInt8Vector(childRef, key, value);
  }

  /// Replaces a int16 vector value of a given configuration field
  Future<void> setConfigValueInt16Vector(
    ChildRef childRef,
    String key,
    Int16List value,
  ) {
    return rootRealm.setConfigValueInt16Vector(childRef, key, value);
  }

  /// Replaces a int32 vector value of a given configuration field
  Future<void> setConfigValueInt32Vector(
    ChildRef childRef,
    String key,
    Int32List value,
  ) {
    return rootRealm.setConfigValueInt32Vector(childRef, key, value);
  }

  /// Replaces a int64 vector value of a given configuration field
  Future<void> setConfigValueInt64Vector(
    ChildRef childRef,
    String key,
    Int64List value,
  ) {
    return rootRealm.setConfigValueInt64Vector(childRef, key, value);
  }

  /// Replaces a string vector value of a given configuration field
  Future<void> setConfigValueStringVector(
    ChildRef childRef,
    String key,
    List<String> value,
  ) {
    return rootRealm.setConfigValueStringVector(childRef, key, value);
  }

  /// Adds a route between components within the realm
  Future<void> addRoute(Route route) {
    return rootRealm.addRoute(route);
  }

  /// Returns the [RealmInstance] so the test can interact with its child
  /// components.
  Future<RealmInstance> build({String? childName}) async {
    final rootUrl =
        await builder.build(rootRealm._localComponentRunnerBuilder.build());
    final root = await ScopedInstance.create(
      childName: childName,
      collectionName: collectionName,
      url: rootUrl,
    );
    root.connectToBinder();
    return RealmInstance(root);
  }
}
