// 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 <fidl/fuchsia.device/cpp/wire.h>
#include <lib/devmgr-integration-test/fixture.h>

#include <ddktl/device.h>
#include <zxtest/zxtest.h>

#include "src/devices/testing/mock-ddk/mock-device.h"

namespace {

using devmgr_integration_test::IsolatedDevmgr;

TEST(MetadataTest, RunTests) {
  const char kDriver[] = "ddk-metadata-test-driver.cm";
  auto args = IsolatedDevmgr::DefaultArgs();

  args.root_device_driver = "/boot/meta/test-parent-sys.cm";

  // NB: this loop is never run. RealmBuilder::Build is in the call stack, and insists on a non-null
  // dispatcher.
  //
  // TODO(https://fxbug.dev/42065538): Remove this.
  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  zx::result devmgr = IsolatedDevmgr::Create(std::move(args), loop.dispatcher());
  ASSERT_OK(devmgr.status_value());

  fidl::ClientEnd<fuchsia_device::Controller> client_end;
  {
    zx::result channel = device_watcher::RecursiveWaitForFile(devmgr.value().devfs_root().get(),
                                                              "sys/test/test/device_controller");
    ASSERT_OK(channel);
    client_end.channel() = std::move(channel.value());
  }
  fidl::WireSyncClient controller(std::move(client_end));

  const fidl::WireResult result = controller->Bind(fidl::StringView{kDriver});
  ASSERT_OK(result.status());
  const fit::result response = result.value();
  // The driver will run its tests in its bind routine, and return ZX_OK on success.
  ASSERT_TRUE(response.is_ok(), "%s", zx_status_get_string(response.error_value()));
}

// Test the Metadata struct helper:
TEST(MetadataTest, GetMetadataStructTest) {
  auto parent = MockDevice::FakeRootParent();  // Hold on to the parent during the test.
  constexpr size_t kMetadataType = 5;
  struct MetadataType {
    int data[4];
    float data1;
  };
  MetadataType metadata_source;
  parent->SetMetadata(kMetadataType, &metadata_source, sizeof(metadata_source));

  auto metadata_result = ddk::GetMetadata<MetadataType>(parent.get(), kMetadataType);

  ASSERT_TRUE(metadata_result.is_ok());
  ASSERT_BYTES_EQ(metadata_result.value().get(), &metadata_source, sizeof(MetadataType));
}

// Test the Metadata Array helper:
TEST(MetadataTest, MetadataArrayTests) {
  auto parent = MockDevice::FakeRootParent();  // Hold on to the parent during the test.
  constexpr size_t kMetadataType = 5;
  struct MetadataType {
    int data[4];
    float data1;
  };

  constexpr size_t kMetadataArrayLen = 5;
  MetadataType metadata_source[kMetadataArrayLen];
  parent->SetMetadata(kMetadataType, &metadata_source, sizeof(metadata_source));

  auto metadata_result = ddk::GetMetadataArray<MetadataType>(parent.get(), kMetadataType);

  ASSERT_TRUE(metadata_result.is_ok());
  ASSERT_EQ(metadata_result->size(), kMetadataArrayLen);
  for (size_t i = 0; i < metadata_result->size(); ++i) {
    ASSERT_BYTES_EQ(&metadata_result.value()[i], &metadata_source[i], sizeof(MetadataType));
  }
}

// Simple device to test DeviceAddArgs
class TestDevice : public ddk::Device<TestDevice> {
 public:
  explicit TestDevice(zx_device_t* parent) : ddk::Device<TestDevice>(parent) {}
  void DdkRelease() {
    // DdkRelease must delete this before it returns.
    delete this;
  }
};

TEST(MetadataTest, DeviceAddArgTests) {
  // We use two parents here because if we added the metadata to the normal parent,
  // it would be accessible through the child by recursion.
  auto parent = MockDevice::FakeRootParent();           // Hold on to the parent during the test.
  auto metadata_parent = MockDevice::FakeRootParent();  // This will actually have the metadata
  constexpr size_t kMetadataType = 5;
  struct MetadataType {
    int data[4];
    float data1;
  };

  constexpr size_t kMetadataArrayLen = 5;
  MetadataType metadata_source[kMetadataArrayLen];
  metadata_parent->SetMetadata(kMetadataType, &metadata_source, sizeof(metadata_source));

  // Bind a new device:
  auto dev = std::make_unique<TestDevice>(parent.get());
  // Now, add the child, but allow it to get the metadata from the metadata_parent:
  auto args = ddk::DeviceAddArgs("dut").forward_metadata(metadata_parent.get(), kMetadataType);
  ASSERT_EQ(args.get().metadata_count, 1);
  ASSERT_EQ(args.get().metadata_list[0].type, kMetadataType);

  ASSERT_OK(dev->DdkAdd(args));
  auto dev_ptr = dev.release();

  // Now the metadata should be available in the device:
  auto metadata_result = ddk::GetMetadataArray<MetadataType>(dev_ptr->zxdev(), kMetadataType);

  ASSERT_TRUE(metadata_result.is_ok());
  ASSERT_EQ(metadata_result->size(), kMetadataArrayLen);
  for (size_t i = 0; i < metadata_result->size(); ++i) {
    ASSERT_BYTES_EQ(&metadata_result.value()[i], &metadata_source[i], sizeof(MetadataType));
  }
}

}  // namespace
