// 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 <fs/service.h>
#include <fs/synchronous_vfs.h>
#include <gtest/gtest.h>
#include <test/placeholders/cpp/fidl.h>

#include "lib/gtest/real_loop_fixture.h"
#include "src/lib/fxl/strings/substitute.h"
#include "src/sys/appmgr/service_provider_dir_impl.h"
#include "src/sys/appmgr/util.h"

namespace component {
namespace {

class FakeEcho : public test::placeholders::Echo {
 public:
  FakeEcho(fidl::InterfaceRequest<test::placeholders::Echo> request) : binding_(this) {
    binding_.Bind(std::move(request));
  };
  ~FakeEcho() override {}
  void EchoString(fidl::StringPtr value, EchoStringCallback callback) override {
    callback(answer_);
  }

  void SetAnswer(fidl::StringPtr answer) { answer_ = answer; }

 private:
  fidl::StringPtr answer_;
  ::fidl::Binding<test::placeholders::Echo> binding_;

  FXL_DISALLOW_COPY_AND_ASSIGN(FakeEcho);
};

class ServiceProviderTest : public ::gtest::RealLoopFixture {
 protected:
  ServiceProviderTest() : vfs_(dispatcher()) {}

  fbl::RefPtr<fs::Service> CreateService(int set_value) {
    return fbl::AdoptRef(new fs::Service([this, set_value](zx::channel channel) {
      value_ = set_value;
      return ZX_OK;
    }));
  }

  fbl::RefPtr<fs::Service> CreateEchoService(fidl::StringPtr answer) {
    return fbl::AdoptRef(new fs::Service([this, answer](zx::channel channel) {
      auto echo = std::make_unique<FakeEcho>(
          fidl::InterfaceRequest<test::placeholders::Echo>(std::move(channel)));
      echo->SetAnswer(answer);
      echo_services_.push_back(std::move(echo));
      return ZX_OK;
    }));
  }

  void AddService(ServiceProviderDirImpl* service_provider, const std::string& prefix, int val) {
    AddService(service_provider, prefix, val, CreateService(val));
  }
  void AddService(ServiceProviderDirImpl* service_provider, const std::string& prefix, int i,
                  fbl::RefPtr<fs::Service> svc) {
    const std::string service_name = fxl::Substitute("$0_service$1", prefix, std::to_string(i));
    service_provider->AddService(service_name, svc);
  }

  void GetService(ServiceProviderDirImpl* service_provider, const fbl::String& service_name,
                  fbl::RefPtr<fs::Service>* out) {
    fbl::RefPtr<fs::Vnode> child;
    ASSERT_EQ(ZX_OK, service_provider->Lookup(service_name, &child)) << service_name.c_str();
    *out = fbl::RefPtr<fs::Service>(static_cast<fs::Service*>(child.get()));
  }

  void TestService(ServiceProviderDirImpl* service_provider, const fbl::String& service_name,
                   int expected_value) {
    // Using Lookup.
    value_ = -1;
    fbl::RefPtr<fs::Vnode> child;
    ASSERT_EQ(ZX_OK, service_provider->Lookup(service_name, &child)) << service_name.c_str();
    fbl::RefPtr<fs::Service> child_node;
    GetService(service_provider, service_name, &child_node);
    ASSERT_TRUE(child_node);
    ASSERT_EQ(ZX_OK, vfs_.Serve(child_node, zx::channel(), fs::VnodeConnectionOptions()));
    EXPECT_EQ(expected_value, value_) << service_name.c_str();

    // Using ConnectToService.
    value_ = -1;
    zx::channel h1, h2;
    ASSERT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
    service_provider->ConnectToService(std::string(service_name.data(), service_name.size()),
                                       std::move(h2));
    EXPECT_EQ(expected_value, value_) << service_name.c_str();
  }

  void TestMissingService(ServiceProviderDirImpl* service_provider,
                          const fbl::String& service_name) {
    // Using Lookup.
    value_ = -1;
    fbl::RefPtr<fs::Vnode> child;
    ASSERT_EQ(ZX_ERR_NOT_FOUND, service_provider->Lookup(service_name, &child))
        << service_name.c_str();
    // Never connected to service.
    EXPECT_EQ(value_, -1) << service_name.c_str();

    // Using ConnectToService.
    value_ = -1;
    zx::channel h1, h2;
    ASSERT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
    service_provider->ConnectToService(std::string(service_name.data(), service_name.size()),
                                       std::move(h2));
    // Never connected to service.
    EXPECT_EQ(value_, -1) << service_name.c_str();
  }

  zx::channel OpenAsDirectory(fbl::RefPtr<ServiceProviderDirImpl> service) {
    return Util::OpenAsDirectory(&vfs_, service);
  }

  fs::SynchronousVfs vfs_;
  int value_ = 0;
  std::vector<std::unique_ptr<FakeEcho>> echo_services_;
};

TEST_F(ServiceProviderTest, SimpleService) {
  ServiceProviderDirImpl service_provider(fbl::AdoptRef(new LogConnectorImpl("test")));
  AddService(&service_provider, "my", 1);
  TestService(&service_provider, "my_service1", 1);
  TestMissingService(&service_provider, "nonexistent_service");
}

TEST_F(ServiceProviderTest, Parent) {
  auto service3 = CreateService(3);
  auto service4 = CreateService(4);

  // 'fake_service1' overlaps in parent and child; the child's service should
  // take priority.
  ServiceProviderDirImpl service_provider(fbl::AdoptRef(new LogConnectorImpl("test")));
  AddService(&service_provider, "fake", 1);
  auto parent_service_provider =
      fbl::AdoptRef(new ServiceProviderDirImpl(fbl::AdoptRef(new LogConnectorImpl("parent"))));
  AddService(parent_service_provider.get(), "fake", 1, service3);
  AddService(parent_service_provider.get(), "fake", 2);
  service_provider.set_parent(parent_service_provider);
  AddService(&service_provider, "fake", 2, service4);

  // should call child service
  TestService(&service_provider, "fake_service1", 1);

  // check that we can get parent service, because service4 was added after
  // parent was set
  TestService(&service_provider, "fake_service2", 2);

  // check that parent is able to access its service
  TestService(parent_service_provider.get(), "fake_service1", 3);

  // check nonexistence of bogus service
  TestMissingService(&service_provider, "nonexistent_service");
}

TEST_F(ServiceProviderTest, RestrictedServices) {
  static const std::vector<std::string> kAllowlist{"parent_service1", "my_service1"};
  auto parent_service_provider =
      fbl::AdoptRef(new ServiceProviderDirImpl(AdoptRef(new LogConnectorImpl("parent"))));
  AddService(parent_service_provider.get(), "parent", 1);
  AddService(parent_service_provider.get(), "parent", 2);
  ServiceProviderDirImpl service_provider(AdoptRef(new LogConnectorImpl("main")), &kAllowlist);
  AddService(&service_provider, "my", 1);
  AddService(&service_provider, "my", 2);
  service_provider.set_parent(parent_service_provider);

  // should be able to call "my_service1" and "parent_service1"
  TestService(&service_provider, "my_service1", 1);
  TestService(&service_provider, "parent_service1", 1);

  // "my_service2" and "parent_service2" are not accessible
  TestMissingService(&service_provider, "my_service2");
  TestMissingService(&service_provider, "parent_service2");
}

class DirentChecker {
 public:
  DirentChecker(const void* buffer, size_t length)
      : current_(reinterpret_cast<const uint8_t*>(buffer)), remaining_(length) {}

  void ExpectEnd() { EXPECT_EQ(0u, remaining_); }

  void ExpectEntry(const char* name, uint32_t vtype) {
    ASSERT_NE(0u, remaining_);
    const auto entry = reinterpret_cast<const vdirent_t*>(current_);
    const size_t entry_size = entry->size + sizeof(vdirent_t);
    ASSERT_GE(remaining_, entry_size);
    current_ += entry_size;
    remaining_ -= entry_size;
    const std::string entry_name(entry->name, strlen(name));
    EXPECT_STREQ(entry_name.c_str(), name);
    EXPECT_EQ(VTYPE_TO_DTYPE(vtype), entry->type) << "Unexpected DTYPE for '" << name << "'.";
  }

 private:
  const uint8_t* current_;
  size_t remaining_;
};

constexpr size_t kBufSz = 4096;

TEST_F(ServiceProviderTest, Readdir_Simple) {
  ServiceProviderDirImpl service_provider(AdoptRef(new LogConnectorImpl("test")));
  AddService(&service_provider, "my", 1);
  AddService(&service_provider, "my", 2);
  AddService(&service_provider, "my", 3);

  fs::VdirCookie cookie;
  uint8_t buffer[kBufSz];
  size_t len;
  {
    EXPECT_EQ(ZX_OK, service_provider.Readdir(&cookie, buffer, sizeof(buffer), &len));
    DirentChecker dc(buffer, len);
    dc.ExpectEntry(".", V_TYPE_DIR);
    dc.ExpectEntry("my_service1", V_TYPE_FILE);
    dc.ExpectEntry("my_service2", V_TYPE_FILE);
    dc.ExpectEntry("my_service3", V_TYPE_FILE);
    dc.ExpectEnd();
  }
  {
    EXPECT_EQ(ZX_OK, service_provider.Readdir(&cookie, buffer, sizeof(buffer), &len));
    EXPECT_EQ(len, 0u);
  }
}

TEST_F(ServiceProviderTest, Readdir_WithParent) {
  ServiceProviderDirImpl service_provider(AdoptRef(new LogConnectorImpl("root")));
  AddService(&service_provider, "my", 1);
  AddService(&service_provider, "my", 2);
  auto parent_service_provider =
      fbl::AdoptRef(new ServiceProviderDirImpl(AdoptRef(new LogConnectorImpl("parent"))));
  AddService(parent_service_provider.get(), "parent", 1);
  AddService(parent_service_provider.get(), "parent", 2);
  service_provider.set_parent(parent_service_provider);

  fs::VdirCookie cookie;
  uint8_t buffer[kBufSz];
  size_t len;
  {
    EXPECT_EQ(ZX_OK, service_provider.Readdir(&cookie, buffer, sizeof(buffer), &len));
    DirentChecker dc(buffer, len);
    dc.ExpectEntry(".", V_TYPE_DIR);
    dc.ExpectEntry("my_service1", V_TYPE_FILE);
    dc.ExpectEntry("my_service2", V_TYPE_FILE);
    dc.ExpectEntry("parent_service1", V_TYPE_FILE);
    dc.ExpectEntry("parent_service2", V_TYPE_FILE);
    dc.ExpectEnd();
  }
  {
    EXPECT_EQ(ZX_OK, service_provider.Readdir(&cookie, buffer, sizeof(buffer), &len));
    EXPECT_EQ(len, 0u);
  }
}

// Test that a parent's custom LogSink is inherited by child, and not provided by appmgr.
TEST_F(ServiceProviderTest, CustomLogSinkInheritedFromParent) {
  static const std::vector<std::string> kAllowlist{fuchsia::logger::LogSink::Name_};
  // parent has a custom LogSink.
  auto parent =
      AdoptRef(new ServiceProviderDirImpl(AdoptRef(new LogConnectorImpl("root")), &kAllowlist));
  int parent_logger_requests = 0;
  parent->AddService(fuchsia::logger::LogSink::Name_,
                     fbl::AdoptRef(new fs::Service([&](zx::channel channel) {
                       parent_logger_requests++;
                       return ZX_OK;
                     })));
  parent->InitLogging();

  // child requests a LogSink.
  auto child =
      AdoptRef(new ServiceProviderDirImpl(AdoptRef(new LogConnectorImpl("child")), &kAllowlist));
  child->set_parent(parent);
  child->InitLogging();

  {
    zx::channel client;
    zx::channel server;
    ZX_ASSERT(zx::channel::create(0, &client, &server) == ZX_OK);
    parent->ConnectToService(fuchsia::logger::LogSink::Name_, std::move(server));
    RunLoopUntil([&] { return parent_logger_requests == 1; });
  }
  // test that child connects to parent's custom logsink.
  {
    zx::channel client;
    zx::channel server;
    ZX_ASSERT(zx::channel::create(0, &client, &server) == ZX_OK);
    child->ConnectToService(fuchsia::logger::LogSink::Name_, std::move(server));
    RunLoopUntil([&] { return parent_logger_requests == 2; });
  }
}

// NOTE: We don't test readdir with backing_dir because we know it is broken.
// This will be fixed by removing backing_dir.

}  // namespace
}  // namespace component
