// 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 <zircon/status.h>
#include <zircon/syscalls.h>

#include <memory>

#include <ddk/platform-defs.h>
#include <fbl/unique_fd.h>
#include <gtest/gtest.h>

#include "integration-test.h"

namespace libdriver_integration_test {

class CompositeDeviceTest : public IntegrationTest {
 public:
  static void SetUpTestCase() { DoSetup(true /* should_create_composite */); }

 protected:
  // Create the fragments for the well-known composite that the mock sysdev creates.
  Promise<void> CreateFragmentDevices(std::unique_ptr<RootMockDevice>* root_device,
                                      std::unique_ptr<MockDevice>* child1_device,
                                      std::unique_ptr<MockDevice>* child2_device) {
    fit::bridge<void, Error> child1_bridge;
    fit::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(::fit::error("child1 create abandoned")))
        .and_then(child2_bridge.consumer.promise_or(::fit::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(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;
            };

            fit::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(::fit::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));

            fit::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(::fit::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
