// 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 <fuchsia/device/cpp/fidl.h>
#include <fuchsia/device/test/cpp/fidl.h>
#include <lib/ddk/platform-defs.h>
#include <zircon/status.h>

#include <memory>

#include <gtest/gtest.h>

#include "integration-test.h"

namespace libdriver_integration_test {

class CompositeDeviceTest : public IntegrationTest {
 public:
  static void SetUpTestSuite() { DoSetup(); }

 protected:
  // Create the fragments for the well-known composite that the mock sysdev creates.
  static Promise<void> CreateFragmentDevices(std::unique_ptr<RootMockDevice>* root_device,
                                             std::unique_ptr<MockDevice>* child1_device,
                                             std::unique_ptr<MockDevice>* child2_device) {
    fpromise::bridge<void, Error> child1_bridge;
    fpromise::bridge<void, Error> child2_bridge;
    return ExpectBind(root_device,
                      [=, child1_completer = std::move(child1_bridge.completer),
                       child2_completer = std::move(child2_bridge.completer)](
                          HookInvocation record, Completer<void> completer) mutable {
                        std::vector<zx_device_prop_t> child1_props({
                            {BIND_PLATFORM_DEV_VID, 0, PDEV_VID_TEST},
                            {BIND_PLATFORM_DEV_PID, 0, PDEV_PID_LIBDRIVER_TEST},
                            {BIND_PLATFORM_DEV_DID, 0, PDEV_DID_TEST_CHILD_1},
                        });
                        std::vector<zx_device_prop_t> child2_props({
                            {BIND_PLATFORM_DEV_VID, 0, PDEV_VID_TEST},
                            {BIND_PLATFORM_DEV_PID, 0, PDEV_PID_LIBDRIVER_TEST},
                            {BIND_PLATFORM_DEV_DID, 0, PDEV_DID_TEST_CHILD_2},
                        });
                        ActionList actions;
                        actions.AppendAddMockDevice(loop_.dispatcher(), (*root_device)->path(),
                                                    "fragment1", std::move(child1_props), ZX_OK,
                                                    std::move(child1_completer), child1_device);
                        actions.AppendAddMockDevice(loop_.dispatcher(), (*root_device)->path(),
                                                    "fragment2", std::move(child2_props), ZX_OK,
                                                    std::move(child2_completer), child2_device);
                        actions.AppendReturnStatus(ZX_OK);

                        (*child1_device)->set_hooks(std::make_unique<IgnoreGetProtocol>());
                        (*child2_device)->set_hooks(std::make_unique<IgnoreGetProtocol>());
                        completer.complete_ok();
                        return actions;
                      })
        .and_then(child1_bridge.consumer.promise_or(::fpromise::error("child1 create abandoned")))
        .and_then(child2_bridge.consumer.promise_or(::fpromise::error("child2 create abandoned")));
  }
};

// This test creates two devices that match the well-known composite in the
// test sysdev driver.  It then waits for it to appear in devfs.
TEST_F(CompositeDeviceTest, CreateTest) {
  std::unique_ptr<RootMockDevice> root_device;
  std::unique_ptr<MockDevice> child_device1, child_device2;
  fidl::InterfacePtr<fuchsia::io::Node> client;

  auto promise = CreateFragmentDevices(&root_device, &child_device1, &child_device2)
                     .and_then(DoWaitForPath("composite"))
                     .and_then([&]() -> Promise<void> { return DoOpen("composite", &client); })
                     .and_then([&]() -> Promise<void> {
                       // Destroy the test device.  This should cause an unbind of the child
                       // device.
                       root_device.reset();
                       return JoinPromises(ExpectUnbindThenRelease(child_device1),
                                           ExpectUnbindThenRelease(child_device2));
                     });

  RunPromise(std::move(promise));
}

// TODO(https://fxbug.dev/8452): Re-enable once flake is fixed.
//
// This test creates the well-known composite, and force binds a test driver
// stack to the composite.  It then forces one of the fragments to unbind.
// It verifies that the composite mock-device's unbind hook is called.
TEST_F(CompositeDeviceTest, DISABLED_UnbindFragment) {
  std::unique_ptr<RootMockDevice> root_device, composite_mock;
  std::unique_ptr<MockDevice> child_device1, child_device2, composite_child_device;
  fidl::InterfacePtr<fuchsia::io::Node> client;
  fidl::InterfacePtr<fuchsia::device::Controller> composite, child1_controller;
  fidl::SynchronousInterfacePtr<fuchsia::device::test::RootDevice> composite_test;

  auto promise =
      CreateFragmentDevices(&root_device, &child_device1, &child_device2)
          .and_then(DoWaitForPath("composite"))
          .and_then([&]() -> Promise<void> { return DoWaitForPath("composite/test"); })
          .and_then([&]() -> Promise<void> { return DoOpen("composite/test", &client); })
          .and_then([&]() -> Promise<void> {
            composite_test.Bind(client.Unbind().TakeChannel());

            auto bind_callback = [&composite_mock, &composite_child_device](
                                     HookInvocation record, Completer<void> completer) {
              // Create a test child that we can monitor for hooks.
              ActionList actions;
              actions.AppendAddMockDevice(loop_.dispatcher(), composite_mock->path(), "child",
                                          std::vector<zx_device_prop_t>{}, ZX_OK,
                                          std::move(completer), &composite_child_device);
              actions.AppendReturnStatus(ZX_OK);
              return actions;
            };

            fpromise::bridge<void, Error> bridge;
            auto bind_hook =
                std::make_unique<BindOnce>(std::move(bridge.completer), std::move(bind_callback));
            // Bind the mock device driver to a new child
            zx_status_t status = RootMockDevice::CreateFromTestRoot(
                devmgr_, loop_.dispatcher(), std::move(composite_test), std::move(bind_hook),
                &composite_mock);
            PROMISE_ASSERT(ASSERT_EQ(status, ZX_OK));

            return bridge.consumer.promise_or(::fpromise::error("bind abandoned"));
          })
          .and_then([&]() -> Promise<void> {
            // Open up child1, so we can send it an unbind request
            auto wait_for_open = DoOpen(child_device1->path(), &client);
            auto expect_open = ExpectOpen(child_device1, [](HookInvocation record, uint32_t flags,
                                                            Completer<void> completer) {
              completer.complete_ok();
              ActionList actions;
              actions.AppendReturnStatus(ZX_OK);
              return actions;
            });
            return expect_open.and_then(std::move(wait_for_open));
          })
          .and_then([&]() -> Promise<void> {
            // Send the unbind request to child1
            zx_status_t status =
                child1_controller.Bind(client.Unbind().TakeChannel(), loop_.dispatcher());
            PROMISE_ASSERT(ASSERT_EQ(status, ZX_OK));

            fpromise::bridge<void, Error> bridge;
            child1_controller->ScheduleUnbind(
                [completer = std::move(bridge.completer)](
                    fuchsia::device::Controller_ScheduleUnbind_Result result) mutable {
                  if (result.is_response()) {
                    completer.complete_ok();
                  } else {
                    completer.complete_error(std::string("unbind failed"));
                  }
                });

            // We should receive the unbind for child1, and then soon after for
            // the composite.
            auto unbind_promise =
                ExpectUnbind(child_device1, [](HookInvocation record, Completer<void> completer) {
                  ActionList actions;
                  // We don't care about when the unbind reply actually finishes.
                  // The ExpectRelease below will serialize against it anyway.
                  Promise<void> unbind_reply_done;
                  actions.AppendUnbindReply(&unbind_reply_done);
                  // Complete here instead of in remove device, since the remove
                  // device completion doesn't fire until after we're notified,
                  // which might be after the unbind of the composite begins
                  completer.complete_ok();
                  return actions;
                }).and_then(ExpectUnbindThenRelease(composite_child_device));

            return unbind_promise.and_then(
                bridge.consumer.promise_or(::fpromise::error("Unbind abandoned")));
          })
          .and_then([&]() -> Promise<void> {
            child1_controller.Unbind();
            return ExpectClose(child_device1, [](HookInvocation record, uint32_t flags,
                                                 Completer<void> completer) {
              completer.complete_ok();
              ActionList actions;
              actions.AppendReturnStatus(ZX_OK);
              return actions;
            });
          })
          .and_then(ExpectRelease(child_device1))
          .and_then([&]() -> Promise<void> {
            // Destroy the test device.  This should cause an unbind of the last child
            // device.
            root_device.reset();
            return ExpectUnbindThenRelease(child_device2);
          });

  RunPromise(std::move(promise));
}

}  // namespace libdriver_integration_test
