// Copyright 2016 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 <string.h>

#include <fuchsia/ledger/internal/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/callback/capture.h>
#include <lib/component/cpp/startup_context.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fidl/cpp/synchronous_interface_ptr.h>
#include <lib/fit/function.h>
#include <lib/fsl/io/fd.h>
#include <lib/fsl/vmo/strings.h>
#include <lib/fxl/files/directory.h>
#include <lib/fxl/files/file.h>
#include <lib/gtest/real_loop_fixture.h>
#include <lib/svc/cpp/services.h>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "peridot/bin/ledger/app/serialization_version.h"
#include "peridot/bin/ledger/fidl/include/types.h"
#include "peridot/bin/ledger/filesystem/detached_path.h"
#include "peridot/bin/ledger/filesystem/directory_reader.h"
#include "peridot/bin/ledger/testing/cloud_provider/fake_cloud_provider.h"
#include "peridot/bin/ledger/testing/cloud_provider/types.h"
#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"

namespace test {
namespace e2e_local {
namespace {

using ::testing::ElementsAre;

template <class A>
bool Equals(const fidl::VectorPtr<uint8_t>& a1, const A& a2) {
  if (a1->size() != a2.size())
    return false;
  return memcmp(a1->data(), a2.data(), a1->size()) == 0;
}

fidl::VectorPtr<uint8_t> TestArray() {
  std::string value = "value";
  fidl::VectorPtr<uint8_t> result(value.size());
  memcpy(&result->at(0), &value[0], value.size());
  return result;
}

class LedgerEndToEndTest : public gtest::RealLoopFixture {
 public:
  LedgerEndToEndTest()
      : startup_context_(component::StartupContext::CreateFromStartupInfo()) {}
  ~LedgerEndToEndTest() override {}

 protected:
  void Init(std::vector<std::string> additional_args) {
    component::Services child_services;
    fuchsia::sys::LaunchInfo launch_info;
    launch_info.url = "fuchsia-pkg://fuchsia.com/ledger#meta/ledger.cmx";
    launch_info.directory_request = child_services.NewRequest();
    launch_info.arguments.push_back("--disable_reporting");
    for (auto& additional_arg : additional_args) {
      launch_info.arguments.push_back(additional_arg);
    }
    startup_context()->launcher()->CreateComponent(
        std::move(launch_info), ledger_controller_.NewRequest());

    ledger_controller_.set_error_handler([this](zx_status_t status) {
      for (const auto& callback : ledger_shutdown_callbacks_) {
        callback();
      }
    });

    ledger_repository_factory_.set_error_handler([](zx_status_t status) {
      if (status != ZX_ERR_PEER_CLOSED) {
        ADD_FAILURE() << "Ledger repository error: " << status;
      }
    });
    child_services.ConnectToService(ledger_repository_factory_.NewRequest());
    child_services.ConnectToService(controller_.NewRequest());
  }

  void RegisterShutdownCallback(fit::function<void()> callback) {
    ledger_shutdown_callbacks_.push_back(std::move(callback));
  }

  component::StartupContext* startup_context() {
    return startup_context_.get();
  }

 private:
  fuchsia::sys::ComponentControllerPtr ledger_controller_;
  std::vector<fit::function<void()>> ledger_shutdown_callbacks_;
  std::unique_ptr<component::StartupContext> startup_context_;

 protected:
  ledger_internal::LedgerRepositoryFactoryPtr ledger_repository_factory_;
  fidl::SynchronousInterfacePtr<ledger::Ledger> ledger_;
  fidl::SynchronousInterfacePtr<ledger_internal::LedgerController> controller_;
};

TEST_F(LedgerEndToEndTest, PutAndGet) {
  Init({});
  ledger::Status status;
  fidl::SynchronousInterfacePtr<ledger_internal::LedgerRepository>
      ledger_repository;
  scoped_tmpfs::ScopedTmpFS tmpfs;
  ledger_repository_factory_->GetRepository(
      fsl::CloneChannelFromFileDescriptor(tmpfs.root_fd()), nullptr, "",
      ledger_repository.NewRequest());

  ledger_repository->GetLedger(TestArray(), ledger_.NewRequest());
  ASSERT_EQ(ZX_OK, ledger_repository->Sync());

  fidl::SynchronousInterfacePtr<ledger::Page> page;
  ledger_->GetRootPage(page.NewRequest(), &status);
  ASSERT_EQ(ledger::Status::OK, status);
  page->Put(TestArray(), TestArray(), &status);
  EXPECT_EQ(ledger::Status::OK, status);
  fidl::SynchronousInterfacePtr<ledger::PageSnapshot> snapshot;
  page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
                    nullptr, &status);
  EXPECT_EQ(ledger::Status::OK, status);
  fuchsia::mem::BufferPtr value;
  snapshot->Get(TestArray(), &status, &value);
  EXPECT_EQ(ledger::Status::OK, status);
  std::string value_as_string;
  EXPECT_TRUE(fsl::StringFromVmo(*value, &value_as_string));
  EXPECT_TRUE(Equals(TestArray(), value_as_string));
}

TEST_F(LedgerEndToEndTest, Terminate) {
  Init({});
  bool called = false;
  RegisterShutdownCallback([this, &called] {
    called = true;
    QuitLoop();
  });
  controller_->Terminate();
  RunLoop();
  EXPECT_TRUE(called);
}

// Verifies the cloud erase recovery in case of a cloud that was erased before
// startup.
//
// Expected behavior: Ledger disconnects the clients and the local state is
// cleared.
TEST_F(LedgerEndToEndTest, CloudEraseRecoveryOnInitialCheck) {
  Init({});
  bool ledger_shut_down = false;
  RegisterShutdownCallback([&ledger_shut_down] { ledger_shut_down = true; });

  ledger_internal::LedgerRepositoryPtr ledger_repository;
  scoped_tmpfs::ScopedTmpFS tmpfs;
  const std::string content_path = ledger::kSerializationVersion.ToString();
  const std::string deletion_sentinel_path = content_path + "/sentinel";
  ASSERT_TRUE(files::CreateDirectoryAt(tmpfs.root_fd(), content_path));
  ASSERT_TRUE(
      files::WriteFileAt(tmpfs.root_fd(), deletion_sentinel_path, "", 0));
  ASSERT_TRUE(files::IsFileAt(tmpfs.root_fd(), deletion_sentinel_path));

  // Write a fingerprint file, so that Ledger will check if it is still in the
  // cloud device set.
  const std::string fingerprint_path = content_path + "/fingerprint";
  const std::string fingerprint = "bazinga";
  ASSERT_TRUE(files::WriteFileAt(tmpfs.root_fd(), fingerprint_path,
                                 fingerprint.c_str(), fingerprint.size()));

  // Create a cloud provider configured to trigger the cloude erase recovery on
  // initial check.
  auto cloud_provider =
      ledger::FakeCloudProvider::Builder()
          .SetCloudEraseOnCheck(ledger::CloudEraseOnCheck::YES)
          .Build();
  cloud_provider::CloudProviderPtr cloud_provider_ptr;
  fidl::Binding<cloud_provider::CloudProvider> cloud_provider_binding(
      cloud_provider.get(), cloud_provider_ptr.NewRequest());

  ledger_repository_factory_->GetRepository(
      fsl::CloneChannelFromFileDescriptor(tmpfs.root_fd()),
      std::move(cloud_provider_ptr), "user_id", ledger_repository.NewRequest());

  bool repo_disconnected = false;
  ledger_repository.set_error_handler(
      [&repo_disconnected](zx_status_t status) { repo_disconnected = true; });

  // Run the message loop until Ledger clears the repo directory and disconnects
  // the client.
  RunLoopUntil([&] {
    return !files::IsFileAt(tmpfs.root_fd(), deletion_sentinel_path) &&
           repo_disconnected;
  });
  EXPECT_FALSE(files::IsFileAt(tmpfs.root_fd(), deletion_sentinel_path));
  EXPECT_TRUE(repo_disconnected);

  // Make sure all the contents are deleted. Only the staging directory should
  // be present.
  std::vector<std::string> directory_entries;
  auto on_next_directory_entry = [&](fxl::StringView entry) {
    directory_entries.push_back(entry.ToString());
    return true;
  };
  EXPECT_TRUE(ledger::GetDirectoryEntries(ledger::DetachedPath(tmpfs.root_fd()),
                                          on_next_directory_entry));
  EXPECT_THAT(directory_entries, ElementsAre("staging"));

  // Verify that the Ledger app didn't crash.
  EXPECT_FALSE(ledger_shut_down);
}

// Verifies the cloud erase recovery in case of a cloud that is erased while
// Ledger is connected to it.
//
// Expected behavior: Ledger disconnects the clients and the local state is
// cleared.
TEST_F(LedgerEndToEndTest, CloudEraseRecoveryFromTheWatcher) {
  Init({});
  bool ledger_shut_down = false;
  RegisterShutdownCallback([&ledger_shut_down] { ledger_shut_down = true; });

  ledger_internal::LedgerRepositoryPtr ledger_repository;
  scoped_tmpfs::ScopedTmpFS tmpfs;
  const std::string content_path = ledger::kSerializationVersion.ToString();
  const std::string deletion_sentinel_path = content_path + "/sentinel";
  ASSERT_TRUE(files::CreateDirectoryAt(tmpfs.root_fd(), content_path));
  ASSERT_TRUE(
      files::WriteFileAt(tmpfs.root_fd(), deletion_sentinel_path, "", 0));
  ASSERT_TRUE(files::IsFileAt(tmpfs.root_fd(), deletion_sentinel_path));

  // Create a cloud provider configured to trigger the cloud erase recovery
  // while Ledger is connected.
  auto cloud_provider =
      ledger::FakeCloudProvider::Builder()
          .SetCloudEraseFromWatcher(ledger::CloudEraseFromWatcher::YES)
          .Build();
  cloud_provider::CloudProviderPtr cloud_provider_ptr;
  fidl::Binding<cloud_provider::CloudProvider> cloud_provider_binding(
      cloud_provider.get(), cloud_provider_ptr.NewRequest());

  ledger_repository_factory_->GetRepository(
      fsl::CloneChannelFromFileDescriptor(tmpfs.root_fd()),
      std::move(cloud_provider_ptr), "user_id", ledger_repository.NewRequest());

  bool repo_disconnected = false;
  ledger_repository.set_error_handler(
      [&repo_disconnected](zx_status_t status) { repo_disconnected = true; });

  // Run the message loop until Ledger clears the repo directory and disconnects
  // the client.
  RunLoopUntil([&] {
    return !files::IsFileAt(tmpfs.root_fd(), deletion_sentinel_path) &&
           repo_disconnected;
  });
  EXPECT_FALSE(files::IsFileAt(tmpfs.root_fd(), deletion_sentinel_path));
  EXPECT_TRUE(repo_disconnected);

  // Verify that the Ledger app didn't crash.
  EXPECT_FALSE(ledger_shut_down);
}

// Verifies that Ledger instance continues to work even if the cloud provider
// goes away (for example, because it crashes).
//
// In the future, we need to also be able to reconnect/request a new cloud
// provider, see LE-567.
TEST_F(LedgerEndToEndTest, HandleCloudProviderDisconnectBeforePageInit) {
  Init({});
  bool ledger_app_shut_down = false;
  RegisterShutdownCallback(
      [&ledger_app_shut_down] { ledger_app_shut_down = true; });
  ledger::Status status;
  scoped_tmpfs::ScopedTmpFS tmpfs;

  cloud_provider::CloudProviderPtr cloud_provider_ptr;
  fidl::SynchronousInterfacePtr<ledger_internal::LedgerRepository>
      ledger_repository;
  ledger::FakeCloudProvider cloud_provider;
  fidl::Binding<cloud_provider::CloudProvider> cloud_provider_binding(
      &cloud_provider, cloud_provider_ptr.NewRequest());
  ledger_repository_factory_->GetRepository(
      fsl::CloneChannelFromFileDescriptor(tmpfs.root_fd()),
      std::move(cloud_provider_ptr), "user_id", ledger_repository.NewRequest());

  ledger_repository->GetLedger(TestArray(), ledger_.NewRequest());
  ASSERT_EQ(ZX_OK, ledger_repository->Sync());

  // Close the cloud provider channel.
  cloud_provider_binding.Unbind();

  // Write and read some data to verify that Ledger still works.
  fidl::SynchronousInterfacePtr<ledger::Page> page;
  status = ledger::Status::INTERNAL_ERROR;
  ledger_->GetPage(nullptr, page.NewRequest(), &status);
  ASSERT_EQ(ledger::Status::OK, status);
  status = ledger::Status::INTERNAL_ERROR;
  page->Put(TestArray(), TestArray(), &status);
  EXPECT_EQ(ledger::Status::OK, status);
  fidl::SynchronousInterfacePtr<ledger::PageSnapshot> snapshot;
  status = ledger::Status::INTERNAL_ERROR;
  page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
                    nullptr, &status);
  EXPECT_EQ(ledger::Status::OK, status);
  fuchsia::mem::BufferPtr value;
  status = ledger::Status::INTERNAL_ERROR;
  snapshot->Get(TestArray(), &status, &value);
  ASSERT_EQ(ledger::Status::OK, status);
  std::string value_as_string;
  EXPECT_TRUE(fsl::StringFromVmo(*value, &value_as_string));
  EXPECT_TRUE(Equals(TestArray(), value_as_string));

  // Verify that the Ledger app didn't crash or shut down.
  EXPECT_TRUE(ledger_repository);
  EXPECT_FALSE(ledger_app_shut_down);
}

TEST_F(LedgerEndToEndTest, HandleCloudProviderDisconnectBetweenReadAndWrite) {
  Init({});
  bool ledger_app_shut_down = false;
  RegisterShutdownCallback(
      [&ledger_app_shut_down] { ledger_app_shut_down = true; });
  ledger::Status status;
  scoped_tmpfs::ScopedTmpFS tmpfs;

  cloud_provider::CloudProviderPtr cloud_provider_ptr;
  fidl::SynchronousInterfacePtr<ledger_internal::LedgerRepository>
      ledger_repository;
  ledger::FakeCloudProvider cloud_provider;
  fidl::Binding<cloud_provider::CloudProvider> cloud_provider_binding(
      &cloud_provider, cloud_provider_ptr.NewRequest());
  ledger_repository_factory_->GetRepository(
      fsl::CloneChannelFromFileDescriptor(tmpfs.root_fd()),
      std::move(cloud_provider_ptr), "user_id", ledger_repository.NewRequest());

  ledger_repository->GetLedger(TestArray(), ledger_.NewRequest());
  ASSERT_EQ(ZX_OK, ledger_repository->Sync());

  // Write some data.
  fidl::SynchronousInterfacePtr<ledger::Page> page;
  status = ledger::Status::INTERNAL_ERROR;
  ledger_->GetPage(nullptr, page.NewRequest(), &status);
  ASSERT_EQ(ledger::Status::OK, status);
  status = ledger::Status::INTERNAL_ERROR;
  page->Put(TestArray(), TestArray(), &status);
  EXPECT_EQ(ledger::Status::OK, status);

  // Close the cloud provider channel.
  cloud_provider_binding.Unbind();

  // Read the data back.
  fidl::SynchronousInterfacePtr<ledger::PageSnapshot> snapshot;
  status = ledger::Status::INTERNAL_ERROR;
  page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
                    nullptr, &status);
  EXPECT_EQ(ledger::Status::OK, status);
  fuchsia::mem::BufferPtr value;
  status = ledger::Status::INTERNAL_ERROR;
  snapshot->Get(TestArray(), &status, &value);
  ASSERT_EQ(ledger::Status::OK, status);
  std::string value_as_string;
  EXPECT_TRUE(fsl::StringFromVmo(*value, &value_as_string));
  EXPECT_TRUE(Equals(TestArray(), value_as_string));

  // Verify that the Ledger app didn't crash or shut down.
  EXPECT_TRUE(ledger_repository);
  EXPECT_FALSE(ledger_app_shut_down);
}

}  // namespace
}  // namespace e2e_local
}  // namespace test
