// 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(FLK-344): 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
