// Copyright 2018 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 "src/ledger/bin/app/ledger_repository_factory_impl.h"

#include <fuchsia/inspect/cpp/fidl.h>
#include <lib/callback/capture.h>
#include <lib/callback/set_when_called.h>
#include <lib/fsl/io/fd.h>
#include <lib/inspect/inspect.h>
#include <lib/inspect/reader.h>
#include <lib/inspect/testing/inspect.h>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
#include "src/ledger/bin/app/constants.h"
#include "src/ledger/bin/testing/test_with_environment.h"
#include "src/lib/files/directory.h"
#include "src/lib/files/unique_fd.h"
#include "src/lib/fxl/strings/string_view.h"

namespace ledger {
namespace {

using ::inspect::testing::ChildrenMatch;
using ::inspect::testing::MetricList;
using ::inspect::testing::NameMatches;
using ::inspect::testing::NodeMatches;
using ::inspect::testing::PropertyList;
using ::inspect::testing::UIntMetricIs;
using ::testing::AllOf;
using ::testing::Contains;
using ::testing::IsEmpty;
using ::testing::Not;
using ::testing::UnorderedElementsAre;

constexpr char kTestTopLevelNodeName[] = "top-level-of-test node";
constexpr char kUserID[] = "test user ID";

class LedgerRepositoryFactoryImplTest : public TestWithEnvironment {
 public:
  LedgerRepositoryFactoryImplTest() {
    top_level_inspect_node_ = inspect::Node(kTestTopLevelNodeName);
    repository_factory_ = std::make_unique<LedgerRepositoryFactoryImpl>(
        &environment_, nullptr,
        top_level_inspect_node_.CreateChild(kRepositoriesInspectPathComponent));
  }

  ~LedgerRepositoryFactoryImplTest() override {}

 protected:
  ::testing::AssertionResult CreateDirectory(const std::string& name);
  ::testing::AssertionResult CallGetRepository(
      const std::string& name,
      ledger_internal::LedgerRepositoryPtr* ledger_repository_ptr);

  scoped_tmpfs::ScopedTmpFS tmpfs_;
  inspect::Node top_level_inspect_node_;
  std::unique_ptr<LedgerRepositoryFactoryImpl> repository_factory_;

 private:
  FXL_DISALLOW_COPY_AND_ASSIGN(LedgerRepositoryFactoryImplTest);
};

::testing::AssertionResult LedgerRepositoryFactoryImplTest::CreateDirectory(
    const std::string& name) {
  if (!files::CreateDirectoryAt(tmpfs_.root_fd(), name)) {
    return ::testing::AssertionFailure()
           << "Failed to create directory \"" << name << "\"!";
  }
  return ::testing::AssertionSuccess();
}

::testing::AssertionResult LedgerRepositoryFactoryImplTest::CallGetRepository(
    const std::string& name,
    ledger_internal::LedgerRepositoryPtr* ledger_repository_ptr) {
  fxl::UniqueFD fd(openat(tmpfs_.root_fd(), name.c_str(), O_RDONLY));
  if (!fd.is_valid()) {
    return ::testing::AssertionFailure()
           << "Failed to validate directory \"" << name << "\"!";
  }

  bool callback_called;
  Status status = Status::UNKNOWN_ERROR;

  repository_factory_->GetRepository(
      fsl::CloneChannelFromFileDescriptor(fd.get()), nullptr, kUserID,
      ledger_repository_ptr->NewRequest(),
      callback::Capture(callback::SetWhenCalled(&callback_called), &status));

  if (!callback_called) {
    return ::testing::AssertionFailure()
           << "Callback passed to GetRepository not called!";
  }
  if (status != Status::OK) {
    return ::testing::AssertionFailure() << "Status of GetRepository call was "
                                         << static_cast<int32_t>(status) << "!";
  }
  return ::testing::AssertionSuccess();
}

TEST_F(LedgerRepositoryFactoryImplTest, InspectAPINoRepositories) {
  auto hierarchy = inspect::ReadFromObject(top_level_inspect_node_);
  EXPECT_THAT(
      hierarchy,
      AllOf(NodeMatches(AllOf(NameMatches(kTestTopLevelNodeName),
                              MetricList(IsEmpty()), PropertyList(IsEmpty()))),
            ChildrenMatch(UnorderedElementsAre(NodeMatches(
                AllOf(NameMatches(kRepositoriesInspectPathComponent)))))));
}

TEST_F(LedgerRepositoryFactoryImplTest,
       InspectAPITwoRepositoriesOneAccessedTwice) {
  // The directories in which the two repositories will be created.
  std::string first_directory = "first directory";
  std::string second_directory = "second directory";

  // The names of the two repositories, determined by the
  // LedgerRepositoryFactoryImpl under test.
  std::string first_repository_name;
  std::string second_repository_name;

  // Bindings to the two repositories. If these are not maintained, the
  // LedgerRepositoryFactoryImpl::LedgerRepositoryContainer objects associated
  // with the repositories will be destroyed and the repositories will no
  // longer appear represented in the Inspect API.
  ledger_internal::LedgerRepositoryPtr first_ledger_repository_ptr;
  ledger_internal::LedgerRepositoryPtr second_ledger_repository_ptr;
  ledger_internal::LedgerRepositoryPtr first_again_ledger_repository_ptr;

  // Create the directories for the repositories.
  ASSERT_TRUE(CreateDirectory(first_directory));
  ASSERT_TRUE(CreateDirectory(second_directory));

  // Request one repository, then query the top_level_inspect_node_ (and its
  // children) to verify that that repository is listed (and to learn the name
  // under which it is listed) and that it was requested once.
  ASSERT_TRUE(CallGetRepository(first_directory, &first_ledger_repository_ptr));
  auto top_hierarchy = inspect::ReadFromObject(top_level_inspect_node_);
  auto lone_repository_match = NodeMatches(
      MetricList(Contains(UIntMetricIs(kRequestsInspectPathComponent, 1UL))));
  auto first_inspection_repositories_match =
      AllOf(NodeMatches(NameMatches(kRepositoriesInspectPathComponent)),
            ChildrenMatch(UnorderedElementsAre(lone_repository_match)));
  auto first_inspection_top_level_match =
      ChildrenMatch(UnorderedElementsAre(first_inspection_repositories_match));
  EXPECT_THAT(top_hierarchy, first_inspection_top_level_match);
  first_repository_name =
      top_hierarchy.children()[0].children()[0].node().name();
  EXPECT_THAT(first_repository_name, Not(IsEmpty()));

  // Request a second repository, then query the "repositories" Inspect object
  // to verify that that second repository is listed in addition to the first
  // (and to learn the name under which it is listed) and that the two
  // repositories were each requested once.
  ASSERT_TRUE(
      CallGetRepository(second_directory, &second_ledger_repository_ptr));
  top_hierarchy = inspect::ReadFromObject(top_level_inspect_node_);
  auto second_inspection_two_repositories_match = UnorderedElementsAre(
      NodeMatches(AllOf(NameMatches(first_repository_name),
                        MetricList(Contains(UIntMetricIs(
                            kRequestsInspectPathComponent, 1UL))))),
      NodeMatches(MetricList(
          Contains(UIntMetricIs(kRequestsInspectPathComponent, 1UL)))));
  auto second_inspection_repositories_match = UnorderedElementsAre(
      AllOf(NodeMatches(NameMatches(kRepositoriesInspectPathComponent)),
            ChildrenMatch(second_inspection_two_repositories_match)));
  auto second_inspection_top_level_match =
      ChildrenMatch(second_inspection_repositories_match);
  EXPECT_THAT(top_hierarchy, second_inspection_top_level_match);
  second_repository_name =
      find_if_not(top_hierarchy.children()[0].children().begin(),
                  top_hierarchy.children()[0].children().end(),
                  [&first_repository_name](
                      const inspect::ObjectHierarchy& repository_hierarchy) {
                    return repository_hierarchy.node().name() ==
                           first_repository_name;
                  })
          ->node()
          .name();
  EXPECT_THAT(second_repository_name, Not(IsEmpty()));

  // Request the first repository a second time, then query the "repositories"
  // Inspect object to verify that both repositories remain listed (with their
  // same names) and are described as having been requested twice and once,
  // respectively.
  ASSERT_TRUE(
      CallGetRepository(first_directory, &first_again_ledger_repository_ptr));
  top_hierarchy = inspect::ReadFromObject(top_level_inspect_node_);
  auto third_inspection_two_repositories_match = UnorderedElementsAre(
      NodeMatches(AllOf(NameMatches(first_repository_name),
                        MetricList(Contains(UIntMetricIs(
                            kRequestsInspectPathComponent, 2UL))))),
      NodeMatches(AllOf(NameMatches(second_repository_name),
                        MetricList(Contains(UIntMetricIs(
                            kRequestsInspectPathComponent, 1UL))))));
  auto third_inspection_repositories_match = UnorderedElementsAre(
      AllOf(NodeMatches(NameMatches(kRepositoriesInspectPathComponent)),
            ChildrenMatch(third_inspection_two_repositories_match)));
  auto third_inspection_top_level_match =
      ChildrenMatch(third_inspection_repositories_match);
  EXPECT_THAT(top_hierarchy, third_inspection_top_level_match);
}

TEST_F(LedgerRepositoryFactoryImplTest, CloseOnFilesystemUnavailable) {
  std::unique_ptr<scoped_tmpfs::ScopedTmpFS> tmpfs =
      std::make_unique<scoped_tmpfs::ScopedTmpFS>();
  ledger_internal::LedgerRepositoryPtr ledger_repository_ptr;

  bool get_repository_called;
  Status status = Status::UNKNOWN_ERROR;

  repository_factory_->GetRepository(
      fsl::CloneChannelFromFileDescriptor(tmpfs->root_fd()), nullptr, "",
      ledger_repository_ptr.NewRequest(),
      callback::Capture(callback::SetWhenCalled(&get_repository_called),
                        &status));

  bool channel_closed;
  zx_status_t zx_status;

  ledger_repository_ptr.set_error_handler(
      callback::Capture(callback::SetWhenCalled(&channel_closed), &zx_status));

  RunLoopUntilIdle();

  EXPECT_TRUE(get_repository_called);
  EXPECT_EQ(Status::OK, status);
  EXPECT_FALSE(channel_closed);

  tmpfs.reset();

  RunLoopUntilIdle();

  EXPECT_TRUE(channel_closed);
}

}  // namespace
}  // namespace ledger
