// Copyright 2021 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.

#ifndef LIB_SYS_COMPONENT_CPP_TESTING_REALM_BUILDER_TYPES_H_
#define LIB_SYS_COMPONENT_CPP_TESTING_REALM_BUILDER_TYPES_H_

#include <fuchsia/component/config/cpp/fidl.h>
#include <fuchsia/component/decl/cpp/fidl.h>
#include <fuchsia/component/test/cpp/fidl.h>
#include <fuchsia/io/cpp/fidl.h>
#include <fuchsia/mem/cpp/fidl.h>
#include <lib/async/dispatcher.h>
#include <lib/fdio/namespace.h>
#include <lib/fit/function.h>
#include <lib/sys/cpp/outgoing_directory.h>
#include <lib/sys/cpp/service_directory.h>
#include <zircon/availability.h>

#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <variant>
#include <vector>

// This file contains structs used by the RealmBuilder library to create realms.

namespace component_testing {

class LocalComponentImpl;

namespace internal {
class LocalComponentInstance;
class LocalComponentRunner;
}  // namespace internal

using DependencyType = fuchsia::component::decl::DependencyType;

// A protocol capability. The name refers to the name of the FIDL protocol,
// e.g. `fuchsia.logger.LogSink`.
// See: https://fuchsia.dev/fuchsia-src/concepts/components/v2/capabilities/protocol.
struct Protocol final {
  std::string_view name;
  cpp17::optional<std::string_view> as = cpp17::nullopt;
  cpp17::optional<DependencyType> type = cpp17::nullopt;
  cpp17::optional<std::string_view> path = cpp17::nullopt;
};

// A service capability. The name refers to the name of the FIDL service,
// e.g. `fuchsia.examples.EchoService`.
// See: https://fuchsia.dev/fuchsia-src/concepts/components/v2/capabilities/service.
struct Service final {
  std::string_view name;
  cpp17::optional<std::string_view> as = cpp17::nullopt;
  cpp17::optional<std::string_view> path = cpp17::nullopt;
};

// A directory capability.
// See: https://fuchsia.dev/fuchsia-src/concepts/components/v2/capabilities/directory.
struct Directory final {
  std::string_view name;
  cpp17::optional<std::string_view> as = cpp17::nullopt;
  cpp17::optional<DependencyType> type = cpp17::nullopt;
  cpp17::optional<std::string_view> subdir = cpp17::nullopt;
  cpp17::optional<fuchsia::io::Operations> rights = cpp17::nullopt;
  cpp17::optional<std::string_view> path = cpp17::nullopt;
};

// A storage capability.
// See: https://fuchsia.dev/fuchsia-src/concepts/components/v2/capabilities/storage.
struct Storage final {
  std::string_view name;
  cpp17::optional<std::string_view> as = cpp17::nullopt;
  cpp17::optional<std::string_view> path = cpp17::nullopt;
};

// Routing information for a configuration capability.
struct Config final {
  std::string_view name;
  cpp17::optional<std::string_view> as = cpp17::nullopt;
};

// A capability to be routed from one component to another.
// See: https://fuchsia.dev/fuchsia-src/concepts/components/v2/capabilities
using Capability = cpp17::variant<Protocol, Service, Directory, Storage, Config>;

// [START mock_handles_cpp]
// Handles provided to mock component.
class LocalComponentHandles final {
 public:
  // [START_EXCLUDE]
  LocalComponentHandles(fdio_ns_t* ns, sys::OutgoingDirectory outgoing_dir);
  ~LocalComponentHandles();

  LocalComponentHandles(LocalComponentHandles&&) noexcept;
  LocalComponentHandles& operator=(LocalComponentHandles&&) noexcept;

  LocalComponentHandles(LocalComponentHandles&) = delete;
  LocalComponentHandles& operator=(LocalComponentHandles&) = delete;
  // [END_EXCLUDE]

  // Returns the namespace provided to the mock component. The returned pointer
  // will be invalid once *this is destroyed.
  fdio_ns_t* ns();

  // Returns a wrapper around the component's outgoing directory. The mock
  // component may publish capabilities using the returned object. The returned
  // pointer will be invalid once *this is destroyed.
  sys::OutgoingDirectory* outgoing();

  // Convenience method to construct a ServiceDirectory by opening a handle to
  // "/svc" in the namespace object returned by `ns()`.
  sys::ServiceDirectory svc();

  // [START_EXCLUDE]
 private:
  friend LocalComponentImpl;
  friend internal::LocalComponentInstance;
  friend internal::LocalComponentRunner;

  // Called by LocalComponentImpl::Exit().
  void Exit(zx_status_t return_code = ZX_OK);

  fit::function<void(zx_status_t)> on_exit_;
  fdio_ns_t* namespace_;
  sys::OutgoingDirectory outgoing_dir_;
  // [END_EXCLUDE]
};
// [END mock_handles_cpp]

// [START mock_interface_cpp]
// The interface for backing implementations of components with a Source of Mock.
class LocalComponentImpl {
 public:
  virtual ~LocalComponentImpl();

  // Invoked when the Component Manager issues a Start request to the component.
  // |mock_handles| contains the outgoing directory and namespace of
  // the component.
  virtual void OnStart() = 0;

  // The LocalComponentImpl derived class may override this method to be informed if
  // ComponentController::Stop() was called on the controller associated with
  // the component instance. The ComponentController binding will be dropped
  // automatically, immediately after LocalComponentImpl::OnStop() returns.
  virtual void OnStop() {}

  // The component can call this method to terminate its instance. This will
  // release the handles, and drop the |ComponentController|, informing
  // component manager that the component has stopped. Calling |Exit()| will
  // also cause the Realm to drop the |LocalComponentImpl|, which should
  // destruct the component, and the handles and bindings held by the component.
  // Therefore the |LocalComponentImpl| should not do anything else after
  // calling |Exit()|.
  //
  // This method is not valid until |OnStart()| is invoked.
  void Exit(zx_status_t return_code = ZX_OK);

  // Returns the namespace provided to the mock component.
  //
  // This method is not valid until |OnStart()| is invoked.
  fdio_ns_t* ns();

  // Returns a wrapper around the component's outgoing directory. The mock
  // component may publish capabilities using the returned object.
  //
  // This method is not valid until |OnStart()| is invoked.
  sys::OutgoingDirectory* outgoing();

  // Convenience method to construct a ServiceDirectory by opening a handle to
  // "/svc" in the namespace object returned by `ns()`.
  //
  // This method is not valid until |OnStart()| is invoked.
  sys::ServiceDirectory svc();

 private:
  friend internal::LocalComponentRunner;
  // The |LocalComponentHandles| are set by the |LocalComponentRunner| after
  // construction by the factory, and before calling |OnStart()|
  std::unique_ptr<LocalComponentHandles> handles_;
};
// [END mock_interface_cpp]

// The use of this class is DEPRECATED.
//
// The interface for backing implementations of components with a Source of Mock
// when added by deprecated method AddLocalChild(..., LocalComponent*, ...).
//
// TODO(https://fxbug.dev/296292544): Remove class when build support for API level 16 is removed.
class LocalComponent {
 public:
  virtual ~LocalComponent();

  // Invoked when the Component Manager issues a Start request to the component.
  // |mock_handles| contains the outgoing directory and namespace of
  // the component.
  virtual void Start(std::unique_ptr<LocalComponentHandles> mock_handles) = 0;
} ZX_REMOVED_SINCE(1, 9, 17, "Use LocalComponentFactory instead.");

// Type for a function that returns a new |LocalComponentImpl| when component
// manager requests a new component instance.
//
// See |Realm.AddLocalChild| for more details.
using LocalComponentFactory = fit::function<std::unique_ptr<LocalComponentImpl>()>;

// Type for either variation of implementation passed to AddLocalChild(): the
// deprecated raw pointer, or one of the valid callback functions.
#if __Fuchsia_API_level__ < 17
// TODO(https://fxbug.dev/296292544): Remove variant when build support for API level 16 is removed.
// Ignore warnings caused by the use of the deprecated `LocalComponent` type as it is part of the
// implementation that supports the deprecated type.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
using LocalComponentKind = cpp17::variant<LocalComponent*, LocalComponentFactory>;
#pragma clang diagnostic pop
#else
using LocalComponentKind = cpp17::variant<LocalComponentFactory>;
#endif

using StartupMode = fuchsia::component::decl::StartupMode;

struct ChildOptions {
  // Flag used to determine if component should be started eagerly or not.
  // If started eagerly, then it will start as soon as it's resolved.
  // Otherwise, the component will start once another component requests
  // a capability that it offers.
  StartupMode startup_mode = StartupMode::LAZY;

  // The environment for the child to run in. The environment specified
  // by this field must already exist by the time this is set.
  // Otherwise, calls to AddChild will panic. The referenced string must outlive
  // this object.
  std::string_view environment;

#if __Fuchsia_API_level__ >= 13
  // Structured Configuration overrides to be applied to the child.
  // Only keys declared by the child component as overridable by parent may
  // be provided.
  using ConfigOverride = fuchsia::component::decl::ConfigOverride;
  std::vector<ConfigOverride> config_overrides;
#endif
};

struct SelfRef {};

// If this is used for the root Realm, then this endpoint refers to the test
// component itself. This used to route capabilities to/from the test component.
// If this ise used in a sub Realm, then `Parent` will refer to its parent Realm.
struct ParentRef {};

struct ChildRef {
  std::string_view name;
};

struct CollectionRef {
  std::string_view name;
};

// Only valid as the source of a route; routes the capabilities from the framework.
struct FrameworkRef {};

// Only valid as the source of a route; routes the capabilities with a source of
// "void".
struct VoidRef {};

using Ref = cpp17::variant<ParentRef, ChildRef, CollectionRef, FrameworkRef, VoidRef, SelfRef>;

struct Route {
  std::vector<Capability> capabilities;
  Ref source;
  std::vector<Ref> targets;
};

// A type that specifies the content of a binary file for
// |Realm.RouteReadOnlyDirectory|.
struct BinaryContents {
  // Pointer to bytes of content.
  const void* buffer;

  // Size of content. Only bytes up to this size will be stored.
  size_t size;

  // Offset (optional) to start writing content from |buffer|.
  size_t offset = 0;
};

// An in-memory directory passed to |Realm.RouteReadOnlyDirectory| to
// create directories with files at runtime.
//
// This is useful if a test needs to configure the content of a Directory
// capability provided to a component under test in a Realm.
class DirectoryContents {
 public:
  DirectoryContents() = default;

  // Add a file to this directory with |contents| at destination |path|.
  // Paths can include slashes, e.g. "foo/bar.txt".  However, neither a leading
  // nor a trailing slash must be supplied.
  DirectoryContents& AddFile(std::string_view path, BinaryContents contents);

  // Same as above but allows for a string type for the contents.
  DirectoryContents& AddFile(std::string_view path, std::string_view contents);

 private:
  // Friend class needed in order to invoke |TakeAsFidl|.
  friend class Realm;

  // Take this object and convert it to its FIDL counterpart. Invoking this method
  // resets this object, erasing all previously-added file entries.
  fuchsia::component::test::DirectoryContents TakeAsFidl();

  fuchsia::component::test::DirectoryContents contents_;
};

// Defines a structured configuration value. Used to replace configuration values of existing
// fields of a component.
//
// # Example
//
// ```
// realm_builder.SetConfigValue(echo_server, "echo_string", ConfigValue::String("Hi!"));
// ```
class ConfigValue {
 public:
  ConfigValue() = delete;

  // Implicit type conversion is allowed here to transparently wrap unambiguous types.
  // NOLINTBEGIN(google-explicit-constructor)
  ConfigValue(const char* value);
  ConfigValue(std::string value);
  ConfigValue(std::vector<bool> value);
  ConfigValue(std::vector<uint8_t> value);
  ConfigValue(std::vector<uint16_t> value);
  ConfigValue(std::vector<uint32_t> value);
  ConfigValue(std::vector<uint64_t> value);
  ConfigValue(std::vector<int8_t> value);
  ConfigValue(std::vector<int16_t> value);
  ConfigValue(std::vector<int32_t> value);
  ConfigValue(std::vector<int64_t> value);
  ConfigValue(std::vector<std::string> value);
  // NOLINTEND(google-explicit-constructor)

  ConfigValue(ConfigValue&&) noexcept;
  ConfigValue& operator=(ConfigValue&&) noexcept;
  ConfigValue(const ConfigValue&) = delete;
  ConfigValue& operator=(const ConfigValue&) = delete;
  static ConfigValue Bool(bool value);
  static ConfigValue Uint8(uint8_t value);
  static ConfigValue Uint16(uint16_t value);
  static ConfigValue Uint32(uint32_t value);
  static ConfigValue Uint64(uint64_t value);
  static ConfigValue Int8(int8_t value);
  static ConfigValue Int16(int16_t value);
  static ConfigValue Int32(int32_t value);
  static ConfigValue Int64(int64_t value);

 private:
  // Friend class needed in order to invoke |TakeAsFidl|.
  friend class Realm;

#if __Fuchsia_API_level__ < 13
  fuchsia::component::config::ValueSpec TakeAsFidl();
  explicit ConfigValue(fuchsia::component::config::ValueSpec spec);
  fuchsia::component::config::ValueSpec spec;
#elif __Fuchsia_API_level__ >= 13
  fuchsia::component::decl::ConfigValueSpec TakeAsFidl();
  explicit ConfigValue(fuchsia::component::decl::ConfigValueSpec spec);
  fuchsia::component::decl::ConfigValueSpec spec;
#endif
};

// Defines a configuration capability.
struct ConfigCapability {
  std::string name;
  ConfigValue value;
};

}  // namespace component_testing

#endif  // LIB_SYS_COMPONENT_CPP_TESTING_REALM_BUILDER_TYPES_H_
