// 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 "garnet/bin/appmgr/service_provider_dir_impl.h"

#include <fidl/examples/echo/cpp/fidl.h>
#include <fs/service.h>
#include <fs/synchronous-vfs.h>
#include "garnet/bin/appmgr/util.h"
#include "gtest/gtest.h"
#include "src/lib/fxl/strings/substitute.h"
#include "lib/gtest/real_loop_fixture.h"

namespace component {
namespace {

class FakeEcho : public fidl::examples::echo::Echo {
 public:
  FakeEcho(fidl::InterfaceRequest<fidl::examples::echo::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<fidl::examples::echo::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<fidl::examples::echo::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(&child, service_name))
        << 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(&child, service_name))
        << 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, child_node->Serve(&vfs_, zx::channel(), 0));
    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(fidl::StringPtr(service_name.c_str()),
                                       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(&child, service_name))
        << 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(fidl::StringPtr(service_name.c_str()),
                                       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;
  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;
  AddService(&service_provider, "fake", 1);
  auto parent_service_provider = fbl::AdoptRef(new ServiceProviderDirImpl());
  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> kWhitelist{"parent_service1",
                                                   "my_service1"};
  auto parent_service_provider = fbl::AdoptRef(new ServiceProviderDirImpl);
  AddService(parent_service_provider.get(), "parent", 1);
  AddService(parent_service_provider.get(), "parent", 2);
  ServiceProviderDirImpl service_provider(&kWhitelist);
  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;
  AddService(&service_provider, "my", 1);
  AddService(&service_provider, "my", 2);
  AddService(&service_provider, "my", 3);

  fs::vdircookie_t 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;
  AddService(&service_provider, "my", 1);
  AddService(&service_provider, "my", 2);
  auto parent_service_provider = fbl::AdoptRef(new ServiceProviderDirImpl());
  AddService(parent_service_provider.get(), "parent", 1);
  AddService(parent_service_provider.get(), "parent", 2);
  service_provider.set_parent(parent_service_provider);

  fs::vdircookie_t 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);
  }
}

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