// Copyright 2020 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 "inspect.h"

#include <fs/dir_test_util.h>
#include <sdk/lib/inspect/testing/cpp/zxtest/inspect.h>
#include <zxtest/zxtest.h>

#include "driver_host.h"

namespace {
using inspect::InspectTestHelper;
class DriverHostInspectTestCase : public InspectTestHelper, public zxtest::Test {
 public:
  DriverHostInspectTestCase() : loop_(&kAsyncLoopConfigNoAttachToCurrentThread) {
    loop_.StartThread("dh_inspect_test_thread");
  }

  DriverHostInspect& inspect() { return inspect_; }

 private:
  DriverHostInspect inspect_;
  async::Loop loop_;
};
}  // namespace

TEST_F(DriverHostInspectTestCase, DirectoryEntries) {
  // Check that root inspect is created
  uint8_t buffer[4096];
  size_t length;
  {
    fs::VdirCookie cookie;
    EXPECT_EQ(inspect().diagnostics_dir().Readdir(&cookie, buffer, sizeof(buffer), &length), ZX_OK);
    fs::DirentChecker dc(buffer, length);
    dc.ExpectEntry(".", V_TYPE_DIR);
    dc.ExpectEntry("root.inspect", V_TYPE_FILE);
    dc.ExpectEnd();
  }
}

class DriverInspectTestCase : public InspectTestHelper, public zxtest::Test {
 public:
  DriverInspectTestCase() : driver_host_(&kAsyncLoopConfigNoAttachToCurrentThread) {}

  DriverHostContext& driver_host() { return driver_host_; }

 private:
  DriverHostContext driver_host_;
};

TEST_F(DriverInspectTestCase, DriverProperties) {
  fbl::RefPtr<zx_driver> driver;
  ASSERT_OK(zx_driver::Create("test-driver", driver_host().inspect().drivers(), &driver));
  driver->set_name("test");
  driver->set_status(ZX_OK);
  ReadInspect(driver_host().inspect().inspector());

  // Check properties of test-driver
  auto* test_driver = hierarchy().GetByPath({"drivers", "test-driver"});
  ASSERT_TRUE(test_driver);

  // name: "test"
  ASSERT_NO_FATAL_FAILURES(CheckProperty<inspect::StringPropertyValue>(
      test_driver->node(), "name", inspect::StringPropertyValue("test")));

  // status: 0
  ASSERT_NO_FATAL_FAILURES(CheckProperty<inspect::IntPropertyValue>(
      test_driver->node(), "status", inspect::IntPropertyValue(ZX_OK)));
}

TEST_F(DriverInspectTestCase, AddRemoveDriver) {
  // Get the initial driver count
  ReadInspect(driver_host().inspect().inspector());
  const auto* driver_count =
      hierarchy().node().get_property<inspect::UintPropertyValue>("driver_count");
  ASSERT_TRUE(driver_count);
  auto initial_count = driver_count->value();

  // Add test-driver
  fbl::RefPtr<zx_driver> driver;
  ASSERT_OK(zx_driver::Create("test-driver", driver_host().inspect().drivers(), &driver));

  // Check count is incremented and driver is listed
  ReadInspect(driver_host().inspect().inspector());
  const auto* current_count =
      hierarchy().node().get_property<inspect::UintPropertyValue>("driver_count");
  ASSERT_TRUE(current_count);
  EXPECT_EQ(initial_count + 1, current_count->value());

  auto* test_driver = hierarchy().GetByPath({"drivers", "test-driver"});
  ASSERT_TRUE(test_driver);

  // Destroy driver
  driver.reset();

  // Check count is decremented and device is not listed
  ReadInspect(driver_host().inspect().inspector());
  current_count = hierarchy().node().get_property<inspect::UintPropertyValue>("driver_count");
  ASSERT_TRUE(current_count);
  EXPECT_EQ(initial_count, current_count->value());

  test_driver = hierarchy().GetByPath({"drivers", "test-driver"});
  ASSERT_FALSE(test_driver);
}

class DeviceInspectTestCase : public InspectTestHelper, public zxtest::Test {
 public:
  DeviceInspectTestCase() : driver_host_(&kAsyncLoopConfigNoAttachToCurrentThread) {
    zx_driver::Create("test-driver", driver_host_.inspect().drivers(), &drv_);
  }

  DriverHostContext& driver_host() { return driver_host_; }

  zx_driver* driver() { return drv_.get(); }

 private:
  DriverHostContext driver_host_;
  fbl::RefPtr<zx_driver> drv_;
};

TEST_F(DeviceInspectTestCase, DeviceProperties) {
  fbl::RefPtr<zx_device> device;
  ASSERT_OK(zx_device::Create(&(driver_host()), "test-device", driver(), &device));
  device->set_local_id(1);
  device->set_flag(DEV_FLAG_UNBINDABLE | DEV_FLAG_INITIALIZING);

  ReadInspect(driver_host().inspect().inspector());

  // Check properties of test-device
  auto* test_device = hierarchy().GetByPath({"drivers", "test-driver", "devices", "test-device"});
  ASSERT_TRUE(test_device);
  ASSERT_NO_FATAL_FAILURES(CheckProperty<inspect::UintPropertyValue>(
      test_device->node(), "local_id", inspect::UintPropertyValue(1)));
  ASSERT_NO_FATAL_FAILURES(CheckProperty<inspect::StringPropertyValue>(
      test_device->node(), "flags", inspect::StringPropertyValue("initializing unbindable ")));

  device->set_local_id(0);
  device->vnode.reset();
}

TEST_F(DeviceInspectTestCase, AddRemoveDevice) {
  fbl::RefPtr<zx_device> device;

  ASSERT_OK(zx_device::Create(&(driver_host()), std::string("test-device"), driver(), &device));

  // Check the device count and check that device is listed
  ReadInspect(driver_host().inspect().inspector());
  auto* test_driver = hierarchy().GetByPath({"drivers", "test-driver"});
  ASSERT_TRUE(test_driver);
  const auto* device_count =
      test_driver->node().get_property<inspect::UintPropertyValue>("device_count");
  ASSERT_TRUE(device_count);
  auto initial_count = device_count->value();
  ASSERT_EQ(initial_count, 1);

  auto* test_device = hierarchy().GetByPath({"drivers", "test-driver", "devices", "test-device"});
  ASSERT_TRUE(test_device);

  // Destroy the device
  // Note: This only makes the device to be marked as dead; driver_host holds onto the list of dead
  // devices
  device->vnode.reset();
  device.reset();

  // Check count decremented and device is not listed
  ReadInspect(driver_host().inspect().inspector());
  test_driver = hierarchy().GetByPath({"drivers", "test-driver"});
  ASSERT_TRUE(test_driver);
  device_count = test_driver->node().get_property<inspect::UintPropertyValue>("device_count");
  ASSERT_TRUE(device_count);
  EXPECT_EQ(device_count->value(), 0);

  test_device = hierarchy().GetByPath({"drivers", "test-driver", "devices", "test-device"});
  ASSERT_FALSE(test_device);
}

TEST_F(DeviceInspectTestCase, CallStats) {
  fbl::RefPtr<zx_device> device;
  ASSERT_OK(zx_device::Create(&(driver_host()), "test-device", driver(), &device));
  device->set_ops(&internal::kDeviceDefaultOps);
  device->vnode.reset();

  // Make op calls
  device->ReadOp(nullptr, 0, 0, nullptr);
  device->WriteOp(nullptr, 0, 0, nullptr);
  fidl_incoming_msg_t dummy_msg = {};
  fidl_message_header_t dummy_hdr = {};
  dummy_msg.bytes = static_cast<void*>(&dummy_hdr);
  device->MessageOp(&dummy_msg, nullptr);

  {
    // Test InspectCallStats::Update() method
    driver_host().inspect().DeviceCreateStats().Update();
  }

  // Check call stats
  ReadInspect(driver_host().inspect().inspector());
  auto* call_stats =
      hierarchy().GetByPath({"drivers", "test-driver", "devices", "test-device", "call_stats"});
  ASSERT_TRUE(call_stats);

  auto* read_op_stat = call_stats->GetByPath({"read_op"});
  ASSERT_TRUE(read_op_stat);
  ASSERT_NO_FATAL_FAILURES(CheckProperty<inspect::UintPropertyValue>(
      read_op_stat->node(), "count", inspect::UintPropertyValue(1)));

  auto* write_op_stat = call_stats->GetByPath({"write_op"});
  ASSERT_TRUE(write_op_stat);
  ASSERT_NO_FATAL_FAILURES(CheckProperty<inspect::UintPropertyValue>(
      write_op_stat->node(), "count", inspect::UintPropertyValue(1)));

  auto* message_op_stat = call_stats->GetByPath({"message_op"});
  ASSERT_TRUE(message_op_stat);
  ASSERT_NO_FATAL_FAILURES(CheckProperty<inspect::UintPropertyValue>(
      message_op_stat->node(), "count", inspect::UintPropertyValue(1)));

  auto* device_create_stat = hierarchy().GetByPath({"call_stats", "device_create"});
  ASSERT_TRUE(device_create_stat);
  ASSERT_NO_FATAL_FAILURES(CheckProperty<inspect::UintPropertyValue>(
      device_create_stat->node(), "count", inspect::UintPropertyValue(1)));
}

TEST_F(DeviceInspectTestCase, ParentChild) {
  fbl::RefPtr<zx_device> parent;
  ASSERT_OK(zx_device::Create(&(driver_host()), "test-parent", driver(), &parent));
  parent->set_local_id(2);

  fbl::RefPtr<zx_device> child;
  ASSERT_OK(zx_device::Create(&(driver_host()), "test-child", driver(), &child));
  child->set_local_id(3);
  child->set_parent(parent);
  parent->add_child(child.get());

  // Check parent-child fields in inspect
  ReadInspect(driver_host().inspect().inspector());
  auto* parent_data = hierarchy().GetByPath({"drivers", "test-driver", "devices", "test-parent"});
  ASSERT_TRUE(parent_data);
  auto* child_data = hierarchy().GetByPath({"drivers", "test-driver", "devices", "test-child"});
  ASSERT_TRUE(child_data);

  ASSERT_NO_FATAL_FAILURES(CheckProperty<inspect::UintPropertyValue>(
      parent_data->node(), "child_count", inspect::UintPropertyValue(1)));

  ASSERT_NO_FATAL_FAILURES(CheckProperty<inspect::StringPropertyValue>(
      child_data->node(), "parent", inspect::StringPropertyValue("test-parent (local-id:2)")));

  child->set_local_id(0);
  child->vnode.reset();
  parent->set_local_id(0);
  parent->vnode.reset();
}
