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

#include <fuchsia/component/config/cpp/fidl.h>
#include <fuchsia/component/cpp/fidl.h>
#include <fuchsia/component/decl/cpp/fidl.h>
#include <fuchsia/component/runner/cpp/fidl.h>
#include <fuchsia/component/test/cpp/fidl.h>
#include <fuchsia/io/cpp/fidl.h>
#include <lib/async/default.h>
#include <lib/async/dispatcher.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/io.h>
#include <lib/fidl/cpp/interface_handle.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/sys/component/cpp/testing/internal/convert.h>
#include <lib/sys/component/cpp/testing/internal/errors.h>
#include <lib/sys/component/cpp/testing/internal/local_component_runner.h>
#include <lib/sys/component/cpp/testing/internal/realm.h>
#include <lib/sys/component/cpp/testing/realm_builder.h>
#include <lib/sys/component/cpp/testing/realm_builder_types.h>
#include <lib/sys/component/cpp/testing/scoped_child.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/sys/cpp/service_directory.h>
#include <zircon/assert.h>
#include <zircon/errors.h>

#include <cstddef>
#include <functional>
#include <memory>
#include <optional>
#include <sstream>
#include <utility>
#include <vector>

namespace component_testing {
namespace {
constexpr char kFrameworkIntermediaryChildName[] = "realm_builder_server";
constexpr char kChildPathSeparator[] = "/";

fidl::InterfaceHandle<fuchsia::io::Directory> CreatePkgDirHandle() {
  int fd;
  ZX_COMPONENT_ASSERT_STATUS_OK(
      "fdio_open_fd", fdio_open_fd("/pkg",
                                   static_cast<uint32_t>(fuchsia::io::OpenFlags::RIGHT_READABLE |
                                                         fuchsia::io::OpenFlags::RIGHT_EXECUTABLE),
                                   &fd));
  zx_handle_t handle;
  ZX_COMPONENT_ASSERT_STATUS_OK("fdio_fd_transfer", fdio_fd_transfer(fd, &handle));
  auto channel = zx::channel(handle);
  return fidl::InterfaceHandle<fuchsia::io::Directory>(std::move(channel));
}

}  // namespace

// Implementation methods for Realm.

Realm& Realm::AddChild(const std::string& child_name, const std::string& url,
                       const ChildOptions& options) {
  fuchsia::component::test::Realm_AddChild_Result result;
  ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
      "Realm/AddChild",
      realm_proxy_->AddChild(child_name, url, internal::ConvertToFidl(options), &result), result);
  return *this;
}

// TODO(https://fxbug.dev/296292544): Remove when build support for API level 16 is removed.
// The newer definition of LocalComponentKind is incompatible with LocalComponent*.
#if __Fuchsia_API_level__ < 17
Realm& Realm::AddLocalChild(const std::string& child_name, LocalComponent* local_impl,
                            const ChildOptions& options) {
  return AddLocalChildImpl(child_name, LocalComponentKind(local_impl), options);
}
#endif

Realm& Realm::AddLocalChild(const std::string& child_name, LocalComponentFactory local_impl,
                            const ChildOptions& options) {
  return AddLocalChildImpl(child_name, LocalComponentKind(std::move(local_impl)), options);
}

Realm& Realm::AddLocalChildImpl(const std::string& child_name, LocalComponentKind local_impl,
                                const ChildOptions& options) {
// TODO(https://fxbug.dev/296292544): Remove when build support for API level 16 is removed.
#if __Fuchsia_API_level__ < 17
// 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"
  if (cpp17::holds_alternative<LocalComponent*>(local_impl)) {
    ZX_SYS_ASSERT_NOT_NULL(cpp17::get<LocalComponent*>(local_impl));
  }
#pragma clang diagnostic pop
#endif
  runner_builder_->Register(GetResolvedName(child_name), std::move(local_impl));
  fuchsia::component::test::Realm_AddLocalChild_Result result;
  ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
      "Realm/AddLocalChild",
      realm_proxy_->AddLocalChild(child_name, internal::ConvertToFidl(options), &result), result);
  return *this;
}

Realm Realm::AddChildRealm(const std::string& child_name, const ChildOptions& options) {
  fuchsia::component::test::RealmSyncPtr sub_realm_proxy;
  std::vector<std::string> sub_realm_scope = scope_;
  sub_realm_scope.push_back(child_name);
  Realm sub_realm(std::move(sub_realm_proxy), runner_builder_, std::move(sub_realm_scope));

  fuchsia::component::test::Realm_AddChildRealm_Result result;
  ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
      "Realm/AddChildRealm",
      realm_proxy_->AddChildRealm(child_name, internal::ConvertToFidl(options),
                                  sub_realm.realm_proxy_.NewRequest(), &result),
      result);
  return sub_realm;
}

Realm& Realm::AddRoute(Route route) {
  auto capabilities = internal::ConvertToFidlVec<Capability, fuchsia::component::test::Capability>(
      route.capabilities);
  auto source = internal::ConvertToFidl(route.source);
  auto target = internal::ConvertToFidlVec<Ref, fuchsia::component::decl::Ref>(route.targets);

  fuchsia::component::test::Realm_AddRoute_Result result;
  ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
      "Realm/AddRoute",
      realm_proxy_->AddRoute(std::move(capabilities), std::move(source), std::move(target),
                             &result),
      result);
  return *this;
}

Realm& Realm::RouteReadOnlyDirectory(const std::string& name, std::vector<Ref> to,
                                     DirectoryContents directory) {
  auto to_fidl = internal::ConvertToFidlVec<Ref, fuchsia::component::decl::Ref>(std::move(to));
  auto directory_fidl = directory.TakeAsFidl();

  fuchsia::component::test::Realm_ReadOnlyDirectory_Result result;
  ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
      "Realm/ReadOnlyDirectory",
      realm_proxy_->ReadOnlyDirectory(name, std::move(to_fidl), std::move(directory_fidl), &result),
      result);

  return *this;
}

Realm& Realm::InitMutableConfigFromPackage(const std::string& name) {
  fuchsia::component::test::Realm_InitMutableConfigFromPackage_Result result;
  ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
      "Realm/InitMutableConfigFromPackage",
      realm_proxy_->InitMutableConfigFromPackage(name, &result), result);
  return *this;
}

Realm& Realm::InitMutableConfigToEmpty(const std::string& name) {
  fuchsia::component::test::Realm_InitMutableConfigToEmpty_Result result;
  ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK("Realm/InitMutableConfigToEmpty",
                                           realm_proxy_->InitMutableConfigToEmpty(name, &result),
                                           result);
  return *this;
}

Realm& Realm::SetConfigValue(const std::string& name, const std::string& key, ConfigValue value) {
  fuchsia::component::test::Realm_SetConfigValue_Result result;
  ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
      "Realm/SetConfigValue", realm_proxy_->SetConfigValue(name, key, value.TakeAsFidl(), &result),
      result);
  return *this;
}

#if __Fuchsia_API_level__ >= FUCHSIA_HEAD
Realm& Realm::AddConfiguration(std::vector<ConfigCapability> configurations) {
  for (ConfigCapability& c : configurations) {
    fuchsia::component::decl::Configuration config;
    config.set_name(c.name);
    config.set_value(std::move(*c.value.TakeAsFidl().mutable_value()));
    fuchsia::component::test::Realm_AddCapability_Result result;
    ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
        "Realm/AddCapability",
        realm_proxy_->AddCapability(
            fuchsia::component::decl::Capability::WithConfig(std::move(config)), &result),
        result);
  }

  return *this;
}
#endif

void Realm::ReplaceComponentDecl(const std::string& child_name,
                                 fuchsia::component::decl::Component decl) {
  fuchsia::component::test::Realm_ReplaceComponentDecl_Result result;
  ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
      "Realm/ReplaceComponentDecl",
      realm_proxy_->ReplaceComponentDecl(child_name, std::move(decl), &result), result);
}

void Realm::ReplaceRealmDecl(fuchsia::component::decl::Component decl) {
  fuchsia::component::test::Realm_ReplaceRealmDecl_Result result;
  ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
      "Realm/ReplaceRealmDecl", realm_proxy_->ReplaceRealmDecl(std::move(decl), &result), result);
}

fuchsia::component::decl::Component Realm::GetComponentDecl(const std::string& child_name) {
  fuchsia::component::test::Realm_GetComponentDecl_Result result;
  ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
      "Realm/GetComponentDecl", realm_proxy_->GetComponentDecl(child_name, &result), result);

  return std::move(result.response().component_decl);
}

fuchsia::component::decl::Component Realm::GetRealmDecl() {
  fuchsia::component::test::Realm_GetRealmDecl_Result result;
  ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK("Realm/GetRealmDecl",
                                           realm_proxy_->GetRealmDecl(&result), result);

  return std::move(result.response().component_decl);
}

Realm::Realm(fuchsia::component::test::RealmSyncPtr realm_proxy,
             std::shared_ptr<internal::LocalComponentRunner::Builder> runner_builder,
             std::vector<std::string> scope)
    : realm_proxy_(std::move(realm_proxy)),
      runner_builder_(std::move(runner_builder)),
      scope_(std::move(scope)) {}

std::string Realm::GetResolvedName(const std::string& child_name) {
  if (scope_.empty()) {
    return child_name;
  }

  std::stringstream path;
  for (const auto& s : scope_) {
    path << s << kChildPathSeparator;
  }
  return path.str() + child_name;
}

// Implementation methods for RealmBuilder.

RealmBuilder RealmBuilder::Create(std::shared_ptr<sys::ServiceDirectory> svc) {
  return CreateImpl(cpp17::nullopt, std::move(svc));
}

RealmBuilder RealmBuilder::CreateFromRelativeUrl(std::string_view fragment_only_url,
                                                 std::shared_ptr<sys::ServiceDirectory> svc) {
  return CreateImpl(fragment_only_url, std::move(svc));
}

RealmBuilder RealmBuilder::CreateImpl(cpp17::optional<std::string_view> fragment_only_url,
                                      std::shared_ptr<sys::ServiceDirectory> svc) {
  if (svc == nullptr) {
    svc = sys::ServiceDirectory::CreateFromNamespace();
  }

  fuchsia::component::test::RealmBuilderFactorySyncPtr factory_proxy;
  auto realm_proxy = internal::CreateRealmPtr(svc);
  auto child_ref = fuchsia::component::decl::ChildRef{.name = kFrameworkIntermediaryChildName};
  auto exposed_dir = internal::OpenExposedDir(realm_proxy.get(), child_ref);
  zx_status_t status = fdio_service_connect_at(exposed_dir.channel().get(),
                                               fuchsia::component::test::RealmBuilderFactory::Name_,
                                               factory_proxy.NewRequest().TakeChannel().release());
  ZX_COMPONENT_ASSERT_STATUS_OK("RealmBuilderFactory/Create", status);
  fuchsia::component::test::BuilderSyncPtr builder_proxy;
  fuchsia::component::test::RealmSyncPtr test_realm_proxy;
  if (fragment_only_url.has_value()) {
    ZX_ASSERT_MSG(!fragment_only_url.value().empty(), "fragment_only_url can't be empty");

    fuchsia::component::test::RealmBuilderFactory_CreateFromRelativeUrl_Result result;
    ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
        "RealmBuilderFactory/CreateFromRelativeUrl",
        factory_proxy->CreateFromRelativeUrl(CreatePkgDirHandle(), fragment_only_url.value().data(),
                                             test_realm_proxy.NewRequest(),
                                             builder_proxy.NewRequest(), &result),
        result);
  } else {
    fuchsia::component::test::RealmBuilderFactory_Create_Result result;
    ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
        "RealmBuilderFactory/Create",
        factory_proxy->Create(CreatePkgDirHandle(), test_realm_proxy.NewRequest(),
                              builder_proxy.NewRequest(), &result),
        result);
  }
  return RealmBuilder(svc, std::move(builder_proxy), std::move(test_realm_proxy));
}

RealmBuilder& RealmBuilder::AddChild(const std::string& child_name, const std::string& url,
                                     const ChildOptions& options) {
  ZX_ASSERT_MSG(!child_name.empty(), "child_name can't be empty");
  ZX_ASSERT_MSG(!url.empty(), "url can't be empty");

  root_.AddChild(child_name, url, options);
  return *this;
}

// TODO(https://fxbug.dev/296292544): Remove when build support for API level 16 is removed.
// The newer definition of LocalComponentKind, which is a parameter to AddLocalChildImpl(), is
// incompatible with LocalComponent*.
#if __Fuchsia_API_level__ < 17
RealmBuilder& RealmBuilder::AddLocalChild(const std::string& child_name, LocalComponent* local_impl,
                                          const ChildOptions& options) {
  ZX_ASSERT_MSG(!child_name.empty(), "child_name can't be empty");
  ZX_ASSERT_MSG(local_impl != nullptr, "local_impl can't be nullptr");
  root_.AddLocalChildImpl(child_name, local_impl, options);
  return *this;
}
#endif

RealmBuilder& RealmBuilder::AddLocalChild(const std::string& child_name,
                                          LocalComponentFactory local_impl,
                                          const ChildOptions& options) {
  ZX_ASSERT_MSG(!child_name.empty(), "child_name can't be empty");
  root_.AddLocalChildImpl(child_name, LocalComponentKind(std::move(local_impl)), options);
  return *this;
}

Realm RealmBuilder::AddChildRealm(const std::string& child_name, const ChildOptions& options) {
  ZX_ASSERT_MSG(!child_name.empty(), "child_name can't be empty");
  return root_.AddChildRealm(child_name, options);
}

RealmBuilder& RealmBuilder::AddRoute(Route route) {
  ZX_ASSERT_MSG(!route.capabilities.empty(), "route.capabilities can't be empty");
  ZX_ASSERT_MSG(!route.targets.empty(), "route.targets can't be empty");

  root_.AddRoute(std::move(route));
  return *this;
}

RealmBuilder& RealmBuilder::RouteReadOnlyDirectory(const std::string& name, std::vector<Ref> to,
                                                   DirectoryContents directory) {
  root_.RouteReadOnlyDirectory(name, std::move(to), std::move(directory));
  return *this;
}

RealmBuilder& RealmBuilder::InitMutableConfigFromPackage(const std::string& name) {
  root_.InitMutableConfigFromPackage(name);
  return *this;
}

RealmBuilder& RealmBuilder::InitMutableConfigToEmpty(const std::string& name) {
  root_.InitMutableConfigToEmpty(name);
  return *this;
}

#if __Fuchsia_API_level__ >= FUCHSIA_HEAD
RealmBuilder& RealmBuilder::AddConfiguration(std::vector<ConfigCapability> configurations) {
  root_.AddConfiguration(std::move(configurations));
  return *this;
}
#endif

RealmBuilder& RealmBuilder::SetConfigValue(const std::string& name, const std::string& key,
                                           ConfigValue value) {
  root_.SetConfigValue(name, key, std::move(value));
  return *this;
}

void RealmBuilder::ReplaceComponentDecl(const std::string& child_name,
                                        fuchsia::component::decl::Component decl) {
  root_.ReplaceComponentDecl(child_name, std::move(decl));
}

void RealmBuilder::ReplaceRealmDecl(fuchsia::component::decl::Component decl) {
  root_.ReplaceRealmDecl(std::move(decl));
}

fuchsia::component::decl::Component RealmBuilder::GetComponentDecl(const std::string& child_name) {
  return root_.GetComponentDecl(child_name);
}

fuchsia::component::decl::Component RealmBuilder::GetRealmDecl() { return root_.GetRealmDecl(); }

RealmBuilder& RealmBuilder::SetRealmCollection(const std::string& collection) {
  realm_collection_ = collection;
  return *this;
}

RealmBuilder& RealmBuilder::SetRealmName(const std::string& name) {
  realm_name_ = name;
  return *this;
}

RealmRoot RealmBuilder::Build(async_dispatcher_t* dispatcher) {
  ZX_ASSERT_MSG(!realm_commited_, "Builder::Build() called after Realm already created");
  if (dispatcher == nullptr) {
    dispatcher = async_get_default_dispatcher();
  }
  ZX_ASSERT_MSG(dispatcher != nullptr, "Builder::Build() called without configured dispatcher");
  auto local_component_runner = runner_builder_->Build(dispatcher);
  fuchsia::component::test::Builder_Build_Result result;
  ZX_COMPONENT_ASSERT_STATUS_AND_RESULT_OK(
      "Builder/Build", builder_proxy_->Build(local_component_runner->NewBinding(), &result),
      result);
  realm_commited_ = true;

  auto scoped_child =
      realm_name_.has_value()
          ? ScopedChild::New(realm_collection_, realm_name_.value(),
                             result.response().root_component_url, svc_)
          : ScopedChild::New(realm_collection_, result.response().root_component_url, svc_);

  // Connect to fuchsia.component.Binder to automatically start Realm.
  if (start_on_build_) {
    scoped_child.ConnectSync<fuchsia::component::Binder>();
  }

  return RealmRoot(std::move(local_component_runner), std::move(scoped_child), dispatcher);
}

Realm& RealmBuilder::root() { return root_; }

RealmBuilder::RealmBuilder(std::shared_ptr<sys::ServiceDirectory> svc,
                           fuchsia::component::test::BuilderSyncPtr builder_proxy,
                           fuchsia::component::test::RealmSyncPtr test_realm_proxy)
    : svc_(std::move(svc)),
      builder_proxy_(std::move(builder_proxy)),
      runner_builder_(std::make_shared<internal::LocalComponentRunner::Builder>()),
      root_(Realm(std::move(test_realm_proxy), runner_builder_)) {}

// Implementation methods for RealmRoot.

RealmRoot::RealmRoot(std::unique_ptr<internal::LocalComponentRunner> local_component_runner,
                     ScopedChild root, async_dispatcher_t* dispatcher)
    : local_component_runner_(std::move(local_component_runner)),
      root_(std::move(root)),
      dispatcher_(dispatcher) {}

RealmRoot::~RealmRoot() = default;

zx_status_t RealmRoot::Connect(const std::string& interface_name, zx::channel request) const {
  return root_.Connect(interface_name, std::move(request));
}

std::string RealmRoot::GetChildName() const { return root_.GetChildName(); }

void RealmRoot::Teardown(ScopedChild::TeardownCallback on_teardown_complete) {
  root_.Teardown(dispatcher_, std::move(on_teardown_complete));
}

ScopedChild& RealmRoot::component() { return root_; }

const ScopedChild& RealmRoot::component() const { return root_; }

}  // namespace component_testing
