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

#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/data/cpp/fidl.h>
#include <fuchsia/io/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/loop.h>
#include <lib/async/dispatcher.h>
#include <lib/fdio/namespace.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fidl/cpp/comparison.h>
#include <lib/fidl/cpp/interface_handle.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/fidl/cpp/string.h>
#include <lib/fit/function.h>
#include <lib/sys/component/cpp/testing/internal/convert.h>
#include <lib/sys/component/cpp/testing/internal/local_component_runner.h>
#include <lib/sys/component/cpp/testing/realm_builder_types.h>
#include <lib/sys/component/cpp/tests/utils.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/channel.h>
#include <zircon/status.h>

#include <cstddef>
#include <utility>

#include <gtest/gtest.h>
#include <src/lib/testing/loop_fixture/real_loop_fixture.h>
#include <test/placeholders/cpp/fidl.h>

#include "src/lib/testing/loop_fixture/real_loop_fixture.h"

namespace {

// NOLINTNEXTLINE
using namespace component_testing;
// NOLINTNEXTLINE
using namespace component_testing::internal;

namespace fctest = fuchsia::component::test;
namespace fcdecl = fuchsia::component::decl;
namespace fio = fuchsia::io;

/*
 * Tests for |component_testing::internal::LocalComponentRunner| and
 * |component_testing::internal::LocalComponentRunner::Builder|.
 */

class TestComponent : public LocalComponentImpl {
 public:
  explicit TestComponent(fit::closure quit_loop) : quit_loop_(std::move(quit_loop)) {}

  void OnStart() override {
    called_ = true;
    quit_loop_();
  }

  bool WasCalled() const { return called_; }

 private:
  fit::closure quit_loop_;
  bool called_ = false;
};

class LocalComponentRunnerTest : public gtest::RealLoopFixture {
 public:
  void SetUp() override {
    auto builder = LocalComponentRunner::Builder();
    builder.Register(kTestComponentName, [this]() {
      auto test_component = std::make_unique<TestComponent>(QuitLoopClosure());
      FX_CHECK(test_component_ == nullptr);
      test_component_ = test_component.get();
      return test_component;
    });
    local_component_runner_ = builder.Build(dispatcher());
    runner_proxy_.Bind(local_component_runner_->NewBinding());
  }

  void TearDown() override {
    local_component_runner_.reset();
    default_component_controller_.Unbind();
    runner_proxy_.Unbind();
  }

 protected:
  static constexpr char kTestComponentName[] = "test_component";

  void CallStart(
      fuchsia::component::runner::ComponentStartInfo start_info,
      fidl::InterfaceRequest<fuchsia::component::runner::ComponentController> controller) {
    runner_proxy_->Start(std::move(start_info), std::move(controller));
  }

  void CallStart(fuchsia::component::runner::ComponentStartInfo start_info) {
    CallStart(std::move(start_info), default_component_controller_.NewRequest(dispatcher()));
  }

  TestComponent* GetTestComponent() { return test_component_; }

  static fuchsia::component::runner::ComponentStartInfo CreateValidStartInfo() {
    fuchsia::component::runner::ComponentStartInfo start_info;
    start_info.set_program(CreateValidProgram());
    return start_info;
  }

  static fuchsia::data::Dictionary CreateValidProgram() {
    fuchsia::data::Dictionary program;
    fuchsia::data::DictionaryEntry entry;
    entry.key = fctest::LOCAL_COMPONENT_NAME_KEY;
    auto value = fuchsia::data::DictionaryValue::New();
    value->set_str(kTestComponentName);
    entry.value = std::move(value);
    program.mutable_entries()->push_back(std::move(entry));
    return program;
  }

 private:
  std::unique_ptr<LocalComponentRunner> local_component_runner_ = nullptr;
  TestComponent* test_component_ = nullptr;
  fuchsia::component::runner::ComponentControllerPtr default_component_controller_;
  fuchsia::component::runner::ComponentRunnerPtr runner_proxy_;
};

TEST_F(LocalComponentRunnerTest, RunnerStartsOnStartRequest) {
  CallStart(CreateValidStartInfo());

  RunLoop();

  EXPECT_TRUE(GetTestComponent()->WasCalled());
}

class EchoImpl : public test::placeholders::Echo {
 public:
  void EchoString(::fidl::StringPtr value, EchoStringCallback callback) override {
    callback(std::move(value));
  }
};

TEST_F(LocalComponentRunnerTest, RunnerGivesComponentItsOutgoingDir) {
  auto start_info = CreateValidStartInfo();
  fuchsia::io::DirectoryPtr outgoing_directory_proxy;
  start_info.set_outgoing_dir(outgoing_directory_proxy.NewRequest(dispatcher()));
  EchoImpl echo_impl;
  test::placeholders::EchoPtr echo_proxy;
  fidl::Binding<test::placeholders::Echo> echo_binding(&echo_impl);

  CallStart(std::move(start_info));
  RunLoop();

  ASSERT_EQ(GetTestComponent()->outgoing()->AddPublicService<test::placeholders::Echo>(
                [&](fidl::InterfaceRequest<test::placeholders::Echo> request) {
                  echo_binding.Bind(std::move(request));
                }),
            ZX_OK);
  echo_proxy.Bind(echo_binding.NewBinding(dispatcher()));

  bool echoed = false;
  echo_proxy->EchoString("hello", [&](fidl::StringPtr _) { echoed = true; });
  RunLoopUntil([&]() { return echoed; });
  EXPECT_TRUE(echoed);
}

TEST_F(LocalComponentRunnerTest, RunnerGivesComponentItsNamespace) {
  static constexpr char kNamespacePath[] = "/test/path";

  auto start_info = CreateValidStartInfo();
  fuchsia::component::runner::ComponentNamespaceEntry ns_entry;
  ns_entry.set_path(kNamespacePath);
  zx::channel e1, e2;
  ASSERT_EQ(zx::channel::create(0, &e1, &e2), ZX_OK);
  // We'll provide a valid channel to and verify that it's present down below.
  ns_entry.set_directory(fidl::InterfaceHandle<fuchsia::io::Directory>(std::move(e2)));
  start_info.mutable_ns()->push_back(std::move(ns_entry));

  CallStart(std::move(start_info));
  RunLoop();

  EXPECT_TRUE(fdio_ns_is_bound(GetTestComponent()->ns(), kNamespacePath));
}

/*
 * Tests for |component_testing::internal::Convert*| functions.
 */

template <typename InputType, typename OutputType>
class ConvertParameterizedFixture
    : public testing::TestWithParam<std::pair<InputType, std::shared_ptr<OutputType>>> {
 protected:
  InputType GetInput(const InputType& input) { return input; }
};

#define ZX_COMPONENT_TYPED_TEST_P(test_suite_name, method_name) \
  TEST_P(test_suite_name, method_name) {                        \
    auto param = GetParam();                                    \
    auto actual = ConvertToFidl(GetInput(param.first));         \
    auto expected = std::move(*param.second);                   \
    EXPECT_TRUE(fidl::Equals(actual, expected));                \
  }

// The parameter type must be a copyable type per
// http://google.github.io/googletest/advanced.html#how-to-write-value-parameterized-tests.
// Since at least one member of `ChildOptions` is not copyable, we need to work around this.
// A `std::shared_ptr` is copyable but must be dereferenced to access the value.
// `GetInput()` abstracts the dereferencing when necessary.
class ConvertChildOptionsParameterizedFixture
    : public ConvertParameterizedFixture<std::shared_ptr<ChildOptions>, fctest::ChildOptions> {
 protected:
  const ChildOptions& GetInput(std::shared_ptr<ChildOptions> input) { return *input; }
};

std::vector<fcdecl::ConfigOverride> GetTestConfigOverrides() {
  std::vector<fuchsia::component::decl::ConfigOverride> result;
  result.emplace_back();
  result.back().set_key("baz");
  result.back().set_value(
      fcdecl::ConfigValue::WithSingle(::fcdecl::ConfigSingleValue::WithUint64(1234u)));
  result.emplace_back();
  result.back().set_key("bat");
  result.back().set_value(
      fcdecl::ConfigValue::WithSingle(::fcdecl::ConfigSingleValue::WithInt8(-100)));

  // Add the same key with a different value. There are no checks for duplicates.
  result.emplace_back();
  result.back().set_key(result[0].key());
  result.back().set_value(
      fcdecl::ConfigValue::WithSingle(::fcdecl::ConfigSingleValue::WithString("hello")));

  return result;
}

std::vector<std::pair<std::string, fcdecl::ConfigValue>> GetExpectedConfigOverrides() {
  std::vector<std::pair<std::string, fcdecl::ConfigValue>> result;
  result.emplace_back(std::string("baz"), fcdecl::ConfigValue::WithSingle(
                                              ::fcdecl::ConfigSingleValue::WithUint64(1234u)));
  result.emplace_back(std::string("bat"),
                      fcdecl::ConfigValue::WithSingle(::fcdecl::ConfigSingleValue::WithInt8(-100)));
  result.emplace_back(std::string("baz"), fcdecl::ConfigValue::WithSingle(
                                              ::fcdecl::ConfigSingleValue::WithString("hello")));
  return result;
}

ZX_COMPONENT_TYPED_TEST_P(ConvertChildOptionsParameterizedFixture, ConvertsAllFields)
INSTANTIATE_TEST_SUITE_P(
    ConvertTest, ConvertChildOptionsParameterizedFixture,
    testing::Values(
        std::make_pair(std::shared_ptr<ChildOptions>(new ChildOptions{
                           .startup_mode = StartupMode::EAGER,
                           .environment = "foo",
                           .config_overrides = GetTestConfigOverrides()}),
                       component::tests::CreateFidlChildOptions(StartupMode::EAGER, "foo",
                                                                GetExpectedConfigOverrides())),
        std::make_pair(std::shared_ptr<ChildOptions>(new ChildOptions{
                           .startup_mode = StartupMode::LAZY, .environment = "bar"}),
                       component::tests::CreateFidlChildOptions(StartupMode::LAZY, "bar", {}))));

class ConvertRefParameterizedFixture : public ConvertParameterizedFixture<Ref, fcdecl::Ref> {};

ZX_COMPONENT_TYPED_TEST_P(ConvertRefParameterizedFixture, ConvertsAllFields)
INSTANTIATE_TEST_SUITE_P(
    ConvertTest, ConvertRefParameterizedFixture,
    testing::Values(
        std::make_pair(Ref{ParentRef{}},
                       std::make_shared<fcdecl::Ref>(fcdecl::Ref::WithParent(fcdecl::ParentRef{}))),
        std::make_pair(ChildRef{.name = "foo"}, component::tests::CreateFidlChildRef("foo"))));

class ConvertCapabilityParameterizedFixture
    : public ConvertParameterizedFixture<Capability, fctest::Capability> {};

ZX_COMPONENT_TYPED_TEST_P(ConvertCapabilityParameterizedFixture, ConvertsAllField)
INSTANTIATE_TEST_SUITE_P(
    ConvertTest, ConvertCapabilityParameterizedFixture,
    testing::Values(std::make_pair(Protocol{"foo"},
                                   component::tests::CreateFidlProtocolCapability(/*name=*/"foo")),
                    std::make_pair(Protocol{.name = "foo",
                                            .as = "bar",
                                            .type = fcdecl::DependencyType::WEAK,
                                            .path = "/foo/bar/baz",
                                            .from_dictionary = "source/dict"},
                                   component::tests::CreateFidlProtocolCapability(
                                       /*name=*/"foo", /*as=*/"bar",
                                       /*type=*/fcdecl::DependencyType::WEAK,
                                       /*path=*/"/foo/bar/baz",
                                       /*from_dictionary=*/"source/dict")),
                    std::make_pair(Service{"foo"},
                                   component::tests::CreateFidlServiceCapability(/*name=*/"foo")),
                    std::make_pair(Service{.name = "foo",
                                           .as = "bar",
                                           .path = "/foo/bar/baz",
                                           .from_dictionary = "source/dict"},
                                   component::tests::CreateFidlServiceCapability(
                                       /*name=*/"foo", /*as=*/"bar",
                                       /*path=*/"/foo/bar/baz",
                                       /*from_dictionary=*/"source/dict")),
                    std::make_pair(Directory{"foo"},
                                   component::tests::CreateFidlDirectoryCapability(/*name=*/"foo")),
                    std::make_pair(Directory{.name = "foo",
                                             .as = "bar",
                                             .type = fcdecl::DependencyType::WEAK,
                                             .subdir = "baz",
                                             .rights = fio::Operations::EXECUTE,
                                             .path = "/foo/bar/baz",
                                             .from_dictionary = "source/dict"},
                                   component::tests::CreateFidlDirectoryCapability(
                                       /*name=*/"foo", /*as=*/"bar",
                                       /*type=*/fcdecl::DependencyType::WEAK,
                                       /*subdir=*/"baz",
                                       /*rights=*/fio::Operations::EXECUTE,
                                       /*path=*/"/foo/bar/baz",
                                       /*from_dictionary=*/"source/dict"))));

class ConvertTest : public testing::Test {};

TEST_F(ConvertTest, ToFidlVec) {
  std::vector<fcdecl::Ref> actual_values =
      ConvertToFidlVec<Ref, fcdecl::Ref>({ChildRef{"foo"}, ChildRef{"bar"}});
  std::vector<std::shared_ptr<fcdecl::Ref>> expected_values = {
      component::tests::CreateFidlChildRef("foo"), component::tests::CreateFidlChildRef("bar")};

  ZX_ASSERT(actual_values.size() == expected_values.size());
  for (size_t i = 0; i < expected_values.size(); ++i) {
    auto& actual = actual_values[i];
    auto& expected = (*expected_values[i]);
    EXPECT_TRUE(fidl::Equals(actual, expected));
  }
}

}  // namespace
