// Copyright 2019 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 <fcntl.h>
#include <fuchsia/debugdata/llcpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/wait.h>
#include <lib/debugdata/debugdata.h>
#include <lib/fdio/io.h>
#include <lib/fdio/namespace.h>
#include <lib/fidl-async/cpp/bind.h>
#include <lib/fit/defer.h>
#include <lib/zx/channel.h>
#include <lib/zx/job.h>
#include <lib/zx/vmar.h>
#include <lib/zx/vmo.h>
#include <zircon/sanitizer.h>
#include <zircon/status.h>

#include <filesystem>

#include <fbl/string.h>
#include <fbl/unique_fd.h>
#include <fbl/vector.h>
#include <zxtest/zxtest.h>

#include "src/lib/storage/vfs/cpp/pseudo_dir.h"
#include "src/lib/storage/vfs/cpp/service.h"
#include "src/lib/storage/vfs/cpp/synchronous_vfs.h"
#include "src/lib/storage/vfs/cpp/vmo_file.h"

namespace {

constexpr char kTestSink[] = "test";
constexpr uint8_t kTestData[] = {0x00, 0x11, 0x22, 0x33};

TEST(DebugDataTest, PublishData) {
  async::Loop loop{&kAsyncLoopConfigNoAttachToCurrentThread};
  zx::channel client, server;
  ASSERT_OK(zx::channel::create(0, &client, &server));
  debugdata::DebugData svc(fbl::unique_fd{open("/", O_RDONLY)});
  fidl::BindSingleInFlightOnly(loop.dispatcher(), std::move(server), &svc);

  zx::vmo vmo;
  ASSERT_OK(zx::vmo::create(ZX_PAGE_SIZE, 0, &vmo));
  ASSERT_OK(vmo.write(kTestData, 0, sizeof(kTestData)));

  ASSERT_OK(fidl::WireCall<fuchsia_debugdata::DebugData>(zx::unowned_channel(client))
                .Publish(kTestSink, std::move(vmo))
                .status());

  ASSERT_OK(loop.RunUntilIdle());
  loop.Shutdown();

  const auto& data = svc.data();
  ASSERT_EQ(data.size(), 1);

  ASSERT_NE(data.find(kTestSink), data.end());
  const auto& dump = data.at(kTestSink);
  ASSERT_EQ(dump.size(), 1);

  uint8_t content[sizeof(kTestData)];
  ASSERT_OK(dump[0].read(content, 0, sizeof(content)));
  ASSERT_EQ(memcmp(content, kTestData, sizeof(kTestData)), 0);
}

TEST(DebugDataTest, LoadConfig) {
  async::Loop loop{&kAsyncLoopConfigNoAttachToCurrentThread};
  std::unique_ptr<fs::SynchronousVfs> vfs;

  zx::vmo data;
  ASSERT_OK(zx::vmo::create(ZX_PAGE_SIZE, 0, &data));
  ASSERT_OK(data.write(kTestData, 0, sizeof(kTestData)));

  const std::filesystem::path directory = "/dir";
  const std::filesystem::path filename = "config";

  auto dir = fbl::MakeRefCounted<fs::PseudoDir>();
  dir->AddEntry(filename.c_str(), fbl::MakeRefCounted<fs::VmoFile>(data, 0, sizeof(kTestData)));

  zx::channel c1, c2;
  ASSERT_OK(zx::channel::create(0, &c1, &c2));

  vfs = std::make_unique<fs::SynchronousVfs>(loop.dispatcher());
  ASSERT_OK(vfs->ServeDirectory(std::move(dir), std::move(c1)));
  ASSERT_OK(loop.StartThread());

  fdio_ns_t* ns;
  ASSERT_OK(fdio_ns_get_installed(&ns));
  ASSERT_OK(fdio_ns_bind(ns, directory.c_str(), c2.release()));
  auto unbind = fit::defer([&]() { fdio_ns_unbind(ns, directory.c_str()); });

  async::Loop svc_loop{&kAsyncLoopConfigNoAttachToCurrentThread};
  zx::channel client, server;
  ASSERT_OK(zx::channel::create(0, &client, &server));
  debugdata::DebugData svc(fbl::unique_fd{fdio_ns_opendir(ns)});
  fidl::BindSingleInFlightOnly(svc_loop.dispatcher(), std::move(server), &svc);
  ASSERT_OK(svc_loop.StartThread());

  const auto path = (directory / filename).string();

  auto result = fidl::WireCall<fuchsia_debugdata::DebugData>(zx::unowned_channel(client))
                    .LoadConfig(fidl::StringView::FromExternal(path));
  ASSERT_OK(result.status());
  zx::vmo vmo = std::move(result->config);

  svc_loop.Shutdown();
  loop.Shutdown();
  vfs.reset();

  uint8_t config[sizeof(kTestData)];
  ASSERT_OK(vmo.read(config, 0, sizeof(config)));
  ASSERT_EQ(memcmp(config, kTestData, sizeof(config)), 0);
}

}  // anonymous namespace
