// 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 "device.h"

#include <fidl/fuchsia.sysmem/cpp/fidl.h>
#include <fidl/fuchsia.sysmem/cpp/natural_types.h>
#include <fidl/fuchsia.sysmem2/cpp/fidl.h>
#include <lib/async-loop/default.h>
#include <lib/async-loop/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/fidl/cpp/wire/arena.h>
#include <lib/sync/completion.h>
#include <lib/zx/bti.h>
#include <stdlib.h>
#include <zircon/errors.h>

#include <ddktl/device.h>
#include <ddktl/unbind-txn.h>
#include <zxtest/zxtest.h>

#include "../buffer_collection.h"
#include "../device.h"
#include "../driver.h"
#include "../logical_buffer_collection.h"
#include "src/devices/bus/testing/fake-pdev/fake-pdev.h"
#include "src/devices/testing/mock-ddk/mock-device.h"

namespace sysmem_driver {
namespace {

TEST(Device, OverrideCommandLine) {
  sysmem_driver::Driver sysmem_ctx;
  std::shared_ptr<MockDevice> fake_parent = MockDevice::FakeRootParent();
  sysmem_driver::Device sysmem{fake_parent.get(), &sysmem_ctx};

  const char* kCommandLine = "test.device.commandline";

  int64_t value;
  zx_status_t status;

  value = 10;
  fake_parent->SetVariable(kCommandLine, "5");
  status = sysmem.OverrideSizeFromCommandLine(kCommandLine, &value);
  EXPECT_OK(status);
  EXPECT_EQ(5, value);

  value = 11;
  fake_parent->SetVariable(kCommandLine, "65537");
  status = sysmem.OverrideSizeFromCommandLine(kCommandLine, &value);
  EXPECT_OK(status);
  EXPECT_EQ(65537, value);

  // Trailing characters should cause the entire value to be ignored.
  value = 12;
  fake_parent->SetVariable(kCommandLine, "65536a");
  status = sysmem.OverrideSizeFromCommandLine(kCommandLine, &value);
  EXPECT_EQ(ZX_ERR_INVALID_ARGS, status);
  EXPECT_EQ(12, value);

  // Empty values should be ignored.
  value = 13;
  fake_parent->SetVariable(kCommandLine, "");
  status = sysmem.OverrideSizeFromCommandLine(kCommandLine, &value);
  EXPECT_OK(status);
  EXPECT_EQ(13, value);

  // Negative values are allowed (these get interpreted as a percentage of physical RAM), but only
  // up to 99% is allowed.
  value = 14;
  fake_parent->SetVariable(kCommandLine, "-100");
  status = sysmem.OverrideSizeFromCommandLine(kCommandLine, &value);
  EXPECT_EQ(ZX_ERR_INVALID_ARGS, status);
  EXPECT_EQ(14, value);

  value = 15;
  fake_parent->SetVariable(kCommandLine, "-99");
  status = sysmem.OverrideSizeFromCommandLine(kCommandLine, &value);
  EXPECT_OK(status);
  EXPECT_EQ(-99, value);
}

TEST(Device, GuardPageCommandLine) {
  sysmem_driver::Driver sysmem_ctx;
  std::shared_ptr<MockDevice> fake_parent = MockDevice::FakeRootParent();
  sysmem_driver::Device sysmem{fake_parent.get(), &sysmem_ctx};

  uint64_t guard_bytes = 1;
  bool unused_pages_guarded = true;
  zx::duration unused_page_check_cycle_period;
  bool internal_guard_pages = true;
  bool crash_on_fail = true;
  const char* kName = "driver.sysmem.contiguous_guard_page_count";
  const char* kInternalName = "driver.sysmem.contiguous_guard_pages_internal";

  fake_parent->SetVariable(kInternalName, "");
  EXPECT_EQ(ZX_OK, sysmem.GetContiguousGuardParameters(&guard_bytes, &unused_pages_guarded,
                                                       &unused_page_check_cycle_period,
                                                       &internal_guard_pages, &crash_on_fail));
  EXPECT_EQ(zx_system_get_page_size(), guard_bytes);
  EXPECT_TRUE(unused_pages_guarded);
  EXPECT_EQ(zx::sec(600), unused_page_check_cycle_period);
  EXPECT_TRUE(internal_guard_pages);
  EXPECT_FALSE(crash_on_fail);
  fake_parent->SetVariable(kInternalName, nullptr);

  fake_parent->SetVariable(kName, "fasfas");
  EXPECT_EQ(ZX_ERR_INVALID_ARGS,
            sysmem.GetContiguousGuardParameters(&guard_bytes, &unused_pages_guarded,
                                                &unused_page_check_cycle_period,
                                                &internal_guard_pages, &crash_on_fail));
  EXPECT_EQ(zx_system_get_page_size(), guard_bytes);
  EXPECT_TRUE(unused_pages_guarded);
  EXPECT_EQ(zx::sec(600), unused_page_check_cycle_period);
  EXPECT_FALSE(internal_guard_pages);
  EXPECT_FALSE(crash_on_fail);

  fake_parent->SetVariable(kName, "");
  EXPECT_EQ(ZX_OK, sysmem.GetContiguousGuardParameters(&guard_bytes, &unused_pages_guarded,
                                                       &unused_page_check_cycle_period,
                                                       &internal_guard_pages, &crash_on_fail));
  EXPECT_EQ(zx_system_get_page_size(), guard_bytes);
  EXPECT_TRUE(unused_pages_guarded);
  EXPECT_EQ(zx::sec(600), unused_page_check_cycle_period);
  EXPECT_FALSE(internal_guard_pages);
  EXPECT_FALSE(crash_on_fail);

  fake_parent->SetVariable(kName, "2");
  fake_parent->SetVariable(kInternalName, "");
  EXPECT_EQ(ZX_OK, sysmem.GetContiguousGuardParameters(&guard_bytes, &unused_pages_guarded,
                                                       &unused_page_check_cycle_period,
                                                       &internal_guard_pages, &crash_on_fail));
  EXPECT_EQ(zx_system_get_page_size() * 2, guard_bytes);
  EXPECT_TRUE(unused_pages_guarded);
  EXPECT_EQ(zx::sec(600), unused_page_check_cycle_period);
  EXPECT_TRUE(internal_guard_pages);
  EXPECT_FALSE(crash_on_fail);

  const char* kFatalName = "driver.sysmem.contiguous_guard_pages_fatal";
  fake_parent->SetVariable(kFatalName, "");
  EXPECT_EQ(ZX_OK, sysmem.GetContiguousGuardParameters(&guard_bytes, &unused_pages_guarded,
                                                       &unused_page_check_cycle_period,
                                                       &internal_guard_pages, &crash_on_fail));
  EXPECT_EQ(zx_system_get_page_size() * 2, guard_bytes);
  EXPECT_TRUE(unused_pages_guarded);
  EXPECT_EQ(zx::sec(600), unused_page_check_cycle_period);
  EXPECT_TRUE(internal_guard_pages);
  EXPECT_TRUE(crash_on_fail);

  const char* kUnusedDisabledName = "driver.sysmem.contiguous_guard_pages_unused_disabled";
  fake_parent->SetVariable(kUnusedDisabledName, "");
  EXPECT_EQ(ZX_OK, sysmem.GetContiguousGuardParameters(&guard_bytes, &unused_pages_guarded,
                                                       &unused_page_check_cycle_period,
                                                       &internal_guard_pages, &crash_on_fail));
  EXPECT_EQ(zx_system_get_page_size() * 2, guard_bytes);
  EXPECT_FALSE(unused_pages_guarded);
  EXPECT_EQ(zx::sec(600), unused_page_check_cycle_period);
  EXPECT_TRUE(internal_guard_pages);
  EXPECT_TRUE(crash_on_fail);

  const char* kUnusedCycleSecondsName = "driver.sysmem.contiguous_guard_pages_unused_cycle_seconds";
  fake_parent->SetVariable(kUnusedCycleSecondsName, "42");
  EXPECT_EQ(ZX_OK, sysmem.GetContiguousGuardParameters(&guard_bytes, &unused_pages_guarded,
                                                       &unused_page_check_cycle_period,
                                                       &internal_guard_pages, &crash_on_fail));
  EXPECT_EQ(zx_system_get_page_size() * 2, guard_bytes);
  EXPECT_FALSE(unused_pages_guarded);
  EXPECT_EQ(zx::sec(42), unused_page_check_cycle_period);
  EXPECT_TRUE(internal_guard_pages);
  EXPECT_TRUE(crash_on_fail);
}

class FakeDdkSysmem : public zxtest::Test {
 public:
  FakeDdkSysmem() {}

  void SetUp() override {
    pdev_.SetConfig({
        .use_fake_bti = true,
    });
    EXPECT_OK(pdev_loop_.StartThread());

    auto endpoints = fidl::Endpoints<fuchsia_io::Directory>::Create();

    RunSyncOnLoop(pdev_loop_, [this, server = std::move(endpoints.server)]() mutable {
      outgoing_.emplace(pdev_loop_.dispatcher());
      auto device_handler =
          [this](fidl::ServerEnd<fuchsia_hardware_platform_device::Device> request) {
            fidl::BindServer(pdev_loop_.dispatcher(), std::move(request), &pdev_);
          };
      fuchsia_hardware_platform_device::Service::InstanceHandler handler(
          {.device = std::move(device_handler)});
      auto service_result =
          outgoing_->AddService<fuchsia_hardware_platform_device::Service>(std::move(handler));
      ZX_ASSERT(service_result.is_ok());

      ZX_ASSERT(outgoing_->Serve(std::move(server)).is_ok());
    });

    fake_parent_->AddFidlService(fuchsia_hardware_platform_device::Service::Name,
                                 std::move(endpoints.client));
    EXPECT_EQ(sysmem_->Bind(), ZX_OK);
  }

  void TearDown() override {
    ddk::UnbindTxn txn{sysmem_->zxdev()};
    sysmem_->DdkUnbind(std::move(txn));
    EXPECT_OK(sysmem_->zxdev()->WaitUntilUnbindReplyCalled());
    std::ignore = sysmem_.release();
    loop_.Shutdown();
    RunSyncOnLoop(pdev_loop_, [this] { outgoing_.reset(); });
  }

  fidl::ClientEnd<fuchsia_sysmem::Allocator> Connect() {
    auto [allocator_client_end, allocator_server_end] =
        fidl::Endpoints<fuchsia_sysmem::Allocator>::Create();

    auto [connector_client_end, connector_server_end] =
        fidl::Endpoints<fuchsia_hardware_sysmem::DriverConnector>::Create();

    fidl::BindServer(loop_.dispatcher(), std::move(connector_server_end), sysmem_.get());
    EXPECT_OK(loop_.StartThread());

    auto result = fidl::WireCall(connector_client_end)->ConnectV1(std::move(allocator_server_end));
    EXPECT_OK(result);

    return std::move(allocator_client_end);
  }

  fidl::ClientEnd<fuchsia_sysmem::BufferCollection> AllocateNonSharedCollection() {
    fidl::WireSyncClient<fuchsia_sysmem::Allocator> allocator(Connect());

    auto [collection_client_end, collection_server_end] =
        fidl::Endpoints<fuchsia_sysmem::BufferCollection>::Create();

    EXPECT_OK(allocator->AllocateNonSharedCollection(std::move(collection_server_end)));
    return std::move(collection_client_end);
  }

  void RunSyncOnLoop(async::Loop& loop, fit::closure to_run) {
    sync_completion_t done;
    ZX_ASSERT(ZX_OK ==
              async::PostTask(loop.dispatcher(), [&done, to_run = std::move(to_run)]() mutable {
                std::move(to_run)();
                sync_completion_signal(&done);
              }));
    ZX_ASSERT(ZX_OK == sync_completion_wait_deadline(&done, ZX_TIME_INFINITE));
  }

 protected:
  sysmem_driver::Driver sysmem_ctx_;
  std::shared_ptr<MockDevice> fake_parent_ = MockDevice::FakeRootParent();
  std::unique_ptr<sysmem_driver::Device> sysmem_{new Device{fake_parent_.get(), &sysmem_ctx_}};

  fake_pdev::FakePDevFidl pdev_;

  async::Loop loop_{&kAsyncLoopConfigNeverAttachToThread};
  // Separate loop so we can make sync FIDL calls from loop_ to pdev_loop_.
  async::Loop pdev_loop_{&kAsyncLoopConfigNeverAttachToThread};
  // std::optional<> because outgoing_ can only be created, used, deleted on pdev_loop_
  std::optional<component::OutgoingDirectory> outgoing_;
};

TEST_F(FakeDdkSysmem, TearDownLoop) {
  // Queue up something that would be processed on the FIDL thread, so we can try to detect a
  // use-after-free if the FidlServer outlives the sysmem device.
  AllocateNonSharedCollection();
}

// Test that creating and tearing down a SecureMem connection works correctly.
TEST_F(FakeDdkSysmem, DummySecureMem) {
  auto [client, server] = fidl::Endpoints<fuchsia_sysmem::SecureMem>::Create();
  ASSERT_OK(sysmem_->CommonSysmemRegisterSecureMem(std::move(client)));

  // This shouldn't deadlock waiting for a message on the channel.
  EXPECT_OK(sysmem_->CommonSysmemUnregisterSecureMem());

  // This shouldn't cause a panic due to receiving peer closed.
  client.reset();
}

TEST_F(FakeDdkSysmem, NamedToken) {
  fidl::WireSyncClient<fuchsia_sysmem::Allocator> allocator(Connect());

  auto [token_client_end, token_server_end] =
      fidl::Endpoints<fuchsia_sysmem::BufferCollectionToken>::Create();

  EXPECT_OK(allocator->AllocateSharedCollection(std::move(token_server_end)));

  fidl::WireSyncClient<fuchsia_sysmem::BufferCollectionToken> token(std::move(token_client_end));

  // The buffer collection should end up with a name of "a" because that's the highest priority.
  EXPECT_OK(token->SetName(5u, "c"));
  EXPECT_OK(token->SetName(100u, "a"));
  EXPECT_OK(token->SetName(6u, "b"));

  auto [collection_client_end, collection_server_end] =
      fidl::Endpoints<fuchsia_sysmem::BufferCollection>::Create();

  EXPECT_OK(
      allocator->BindSharedCollection(token.TakeClientEnd(), std::move(collection_server_end)));

  // Poll until a matching buffer collection is found.
  while (true) {
    bool found_collection = false;
    sync_completion_t completion;
    async::PostTask(sysmem_->dispatcher(), [&] {
      if (sysmem_->logical_buffer_collections().size() == 1) {
        const auto* logical_collection = *sysmem_->logical_buffer_collections().begin();
        auto collection_views = logical_collection->collection_views();
        if (collection_views.size() == 1) {
          auto name = logical_collection->name();
          EXPECT_TRUE(name);
          EXPECT_EQ("a", *name);
          found_collection = true;
        }
      }
      sync_completion_signal(&completion);
    });

    sync_completion_wait(&completion, ZX_TIME_INFINITE);
    if (found_collection)
      break;
  }
}

TEST_F(FakeDdkSysmem, NamedClient) {
  auto collection_client_end = AllocateNonSharedCollection();

  fidl::WireSyncClient<fuchsia_sysmem::BufferCollection> collection(
      std::move(collection_client_end));
  EXPECT_OK(collection->SetDebugClientInfo("a", 5));

  // Poll until a matching buffer collection is found.
  while (true) {
    bool found_collection = false;
    sync_completion_t completion;
    async::PostTask(sysmem_->dispatcher(), [&] {
      if (sysmem_->logical_buffer_collections().size() == 1) {
        const auto* logical_collection = *sysmem_->logical_buffer_collections().begin();
        if (logical_collection->collection_views().size() == 1) {
          const BufferCollection* collection = logical_collection->collection_views().front();
          if (collection->node_properties().client_debug_info().name == "a") {
            EXPECT_EQ(5u, collection->node_properties().client_debug_info().id);
            found_collection = true;
          }
        }
      }
      sync_completion_signal(&completion);
    });

    sync_completion_wait(&completion, ZX_TIME_INFINITE);
    if (found_collection)
      break;
  }
}

// Check that the allocator name overrides the collection name.
TEST_F(FakeDdkSysmem, NamedAllocatorToken) {
  fidl::WireSyncClient<fuchsia_sysmem::Allocator> allocator(Connect());

  auto [token_client_end, token_server_end] =
      fidl::Endpoints<fuchsia_sysmem::BufferCollectionToken>::Create();

  EXPECT_OK(allocator->AllocateSharedCollection(std::move(token_server_end)));

  fidl::WireSyncClient<fuchsia_sysmem::BufferCollectionToken> token(std::move(token_client_end));

  EXPECT_OK(token->SetDebugClientInfo("bad", 6));
  EXPECT_OK(allocator->SetDebugClientInfo("a", 5));

  auto [collection_client_end, collection_server_end] =
      fidl::Endpoints<fuchsia_sysmem::BufferCollection>::Create();

  EXPECT_OK(
      allocator->BindSharedCollection(token.TakeClientEnd(), std::move(collection_server_end)));

  // Poll until a matching buffer collection is found.
  while (true) {
    bool found_collection = false;
    sync_completion_t completion;
    async::PostTask(sysmem_->dispatcher(), [&] {
      if (sysmem_->logical_buffer_collections().size() == 1) {
        const auto* logical_collection = *sysmem_->logical_buffer_collections().begin();
        auto collection_views = logical_collection->collection_views();
        if (collection_views.size() == 1) {
          const auto& collection = collection_views.front();
          if (collection->node_properties().client_debug_info().name == "a") {
            EXPECT_EQ(5u, collection->node_properties().client_debug_info().id);
            found_collection = true;
          }
        }
      }
      sync_completion_signal(&completion);
    });

    sync_completion_wait(&completion, ZX_TIME_INFINITE);
    if (found_collection)
      break;
  }
}

TEST_F(FakeDdkSysmem, MaxSize) {
  sysmem_->set_settings(sysmem_driver::Settings{.max_allocation_size = zx_system_get_page_size()});

  auto collection_client = AllocateNonSharedCollection();

  fuchsia_sysmem::BufferCollectionConstraints constraints;
  constraints.min_buffer_count() = 1;
  constraints.has_buffer_memory_constraints() = true;
  constraints.buffer_memory_constraints().min_size_bytes() = zx_system_get_page_size() * 2;
  constraints.buffer_memory_constraints().cpu_domain_supported() = true;
  constraints.usage().cpu() = fuchsia_sysmem::kCpuUsageRead;

  fidl::WireSyncClient<fuchsia_sysmem::BufferCollection> collection(std::move(collection_client));
  fidl::Arena arena;
  EXPECT_OK(collection->SetConstraints(true, fidl::ToWire(arena, std::move(constraints))));

  // Sysmem should fail the collection and return an error.
  fidl::WireResult result = collection->WaitForBuffersAllocated();
  EXPECT_NE(result.status(), ZX_OK);
}

// Check that teardown doesn't leak any memory (detected through LSAN).
TEST_F(FakeDdkSysmem, TeardownLeak) {
  auto collection_client = AllocateNonSharedCollection();

  fuchsia_sysmem::BufferCollectionConstraints constraints;
  constraints.min_buffer_count() = 1;
  constraints.has_buffer_memory_constraints() = true;
  constraints.buffer_memory_constraints().min_size_bytes() = zx_system_get_page_size();
  constraints.buffer_memory_constraints().cpu_domain_supported() = true;
  constraints.usage().cpu() = fuchsia_sysmem::kCpuUsageRead;

  fidl::WireSyncClient<fuchsia_sysmem::BufferCollection> collection(std::move(collection_client));
  fidl::Arena arena;
  EXPECT_OK(collection->SetConstraints(true, fidl::ToWire(arena, std::move(constraints))));

  fidl::WireResult result = collection->WaitForBuffersAllocated();

  EXPECT_OK(result);
  EXPECT_OK(result.value().status);

  for (uint32_t i = 0; i < result.value().buffer_collection_info.buffer_count; i++) {
    result.value().buffer_collection_info.buffers[i].vmo.reset();
  }
  collection = {};
}

// Check that there are no circular references from a VMO to the logical buffer collection.
TEST_F(FakeDdkSysmem, BufferLeak) {
  auto collection_client = AllocateNonSharedCollection();

  fuchsia_sysmem::BufferCollectionConstraints constraints;
  constraints.min_buffer_count() = 1;
  constraints.has_buffer_memory_constraints() = true;
  constraints.buffer_memory_constraints().min_size_bytes() = zx_system_get_page_size();
  constraints.buffer_memory_constraints().cpu_domain_supported() = true;
  constraints.usage().cpu() = fuchsia_sysmem::kCpuUsageRead;

  fidl::WireSyncClient<fuchsia_sysmem::BufferCollection> collection(std::move(collection_client));
  fidl::Arena arena;
  EXPECT_OK(collection->SetConstraints(true, fidl::ToWire(arena, std::move(constraints))));

  fidl::WireResult result = collection->WaitForBuffersAllocated();

  EXPECT_OK(result);
  EXPECT_OK(result.value().status);

  for (uint32_t i = 0; i < result.value().buffer_collection_info.buffer_count; i++) {
    result.value().buffer_collection_info.buffers[i].vmo.reset();
  }

  collection = {};

  // Poll until all buffer collections are deleted.
  while (true) {
    bool no_collections = false;
    sync_completion_t completion;
    async::PostTask(sysmem_->dispatcher(), [&] {
      no_collections = sysmem_->logical_buffer_collections().empty();
      sync_completion_signal(&completion);
    });

    sync_completion_wait(&completion, ZX_TIME_INFINITE);
    if (no_collections)
      break;
  }
}

}  // namespace
}  // namespace sysmem_driver
