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

#include <memory>

#include <fbl/unique_fd.h>
#include <gtest/gtest.h>

#include "integration-test.h"

namespace libdriver_integration_test {

class BasicLifecycleTest : public IntegrationTest {};

// This test checks what happens when a driver returns an error from bind.
TEST_F(BasicLifecycleTest, BindError) {
  std::unique_ptr<RootMockDevice> root_mock_device;

  auto promise =
      ExpectBind(&root_mock_device, [](HookInvocation record, Completer<void> completer) {
        completer.complete_ok();
        ActionList actions;
        actions.AppendReturnStatus(ZX_ERR_NOT_SUPPORTED);
        return actions;
      });
  RunPromise(std::move(promise));
}

// This test confirms that after a device has been added:
// 1) When it's parent is removed, the device receives its unbind() callback.
// 2) If the device calls device_remove() in the unbind() callback, its
//    release() callback gets called later.
TEST_F(BasicLifecycleTest, BindThenUnbindAndRemove) {
  std::unique_ptr<RootMockDevice> root_mock_device;
  std::unique_ptr<MockDevice> mock_child_device;

  auto promise =
      CreateFirstChild(&root_mock_device, &mock_child_device).and_then([&]() -> Promise<void> {
        // Destroy the test device.  This should cause an unbind of the child
        // device.
        root_mock_device.reset();
        return ExpectUnbindThenRelease(mock_child_device);
      });

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

// This test confirms that after a device has been added:
// 1) We can open it via devfs, and its open() hook gets called.
// 2) We can remove the device via device_async_remove() and its unbind() hook gets called
// 3) We can close the opened connection, and its close() and then release() hook gets called.
TEST_F(BasicLifecycleTest, BindThenOpenRemoveAndClose) {
  std::unique_ptr<RootMockDevice> root_mock_device;
  std::unique_ptr<MockDevice> mock_child_device;
  fidl::InterfacePtr<fuchsia::io::Node> client;

  auto promise =
      CreateFirstChild(&root_mock_device, &mock_child_device)
          .and_then([&]() { return DoWaitForPath(mock_child_device->path()); })
          .and_then([&]() {
            // Do the open and wait for acknowledgement that it was successful.
            auto wait_for_open = DoOpen(mock_child_device->path(), &client);
            auto expect_open =
                ExpectOpen(mock_child_device,
                           [](HookInvocation record, uint32_t flags, Completer<void> completer) {
                             completer.complete_ok();
                             ActionList actions;
                             // Request the child device be removed.
                             actions.AppendAsyncRemoveDevice();
                             actions.AppendReturnStatus(ZX_OK);
                             return actions;
                           });
            auto expect_unbind = ExpectUnbind(mock_child_device,
                                              [](HookInvocation record, Completer<void> completer) {
                                                ActionList actions;
                                                actions.AppendUnbindReply(std::move(completer));
                                                return actions;
                                              });
            return expect_open.and_then(std::move(expect_unbind))
                .and_then(std::move(wait_for_open));
          })
          .and_then([&]() {
            // Close the newly opened connection
            client.Unbind();
            return ExpectClose(mock_child_device, [](HookInvocation record, uint32_t flags,
                                                     Completer<void> completer) {
              completer.complete_ok();
              ActionList actions;
              actions.AppendReturnStatus(ZX_OK);
              return actions;
            });
          })
          .and_then([&]() -> Promise<void> {
            // Since DdkAsyncRemove() has been called and all connections have been closed,
            // the device should be released.
            return ExpectRelease(mock_child_device);
          });

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

// This test confirms that after a device has been added:
// 1) We can open it via devfs, and its open() hook gets called.
// 2) We can close the opened connection, and its close() hook gets called.
// 3) Invoking device_remove causes the release hook to run.
TEST_F(BasicLifecycleTest, BindThenOpenCloseAndRemove) {
  std::unique_ptr<RootMockDevice> root_mock_device;
  std::unique_ptr<MockDevice> mock_child_device;
  fidl::InterfacePtr<fuchsia::io::Node> client;

  auto promise =
      CreateFirstChild(&root_mock_device, &mock_child_device)
          .and_then([&]() { return DoWaitForPath(mock_child_device->path()); })
          .and_then([&]() {
            // Do the open and wait for acknowledgement that it was successful.
            auto wait_for_open = DoOpen(mock_child_device->path(), &client);
            auto expect_open =
                ExpectOpen(mock_child_device,
                           [](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([&]() {
            // Close the newly opened connection
            client.Unbind();
            return ExpectClose(mock_child_device, [](HookInvocation record, uint32_t flags,
                                                     Completer<void> completer) {
              completer.complete_ok();
              ActionList actions;
              actions.AppendReturnStatus(ZX_OK);
              return actions;
            });
          })
          .and_then([&]() -> Promise<void> {
            // Destroy the test device.  This should cause an unbind of the child
            // device.
            root_mock_device.reset();
            return ExpectUnbindThenRelease(mock_child_device);
          });

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

// This test confirms that after a device has been added and opened, it won't be
// released until after its been closed.
TEST_F(BasicLifecycleTest, BindThenOpenRemoveThenClose) {
  std::unique_ptr<RootMockDevice> root_mock_device;
  std::unique_ptr<MockDevice> mock_child_device;
  fidl::InterfacePtr<fuchsia::io::Node> client;

  auto promise =
      CreateFirstChild(&root_mock_device, &mock_child_device)
          .and_then([&]() { return DoWaitForPath(mock_child_device->path()); })
          .and_then([&]() {
            // Do the open and wait for acknowledgement that it was successful.
            auto wait_for_open = DoOpen(mock_child_device->path(), &client);
            auto expect_open =
                ExpectOpen(mock_child_device,
                           [](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> {
            // Destroy the test device.  This should cause an unbind of the child
            // device.
            root_mock_device.reset();
            return ExpectUnbind(mock_child_device,
                                [](HookInvocation record, Completer<void> completer) {
                                  ActionList actions;
                                  actions.AppendUnbindReply(std::move(completer));
                                  return actions;
                                });
          })
          .and_then([&]() {
            // Close the newly opened connection.  Release shouldn't be able to
            // happen until then.
            client.Unbind();
            return ExpectClose(mock_child_device, [](HookInvocation record, uint32_t flags,
                                                     Completer<void> completer) {
              completer.complete_ok();
              ActionList actions;
              actions.AppendReturnStatus(ZX_OK);
              return actions;
            });
          })
          .and_then(ExpectRelease(mock_child_device));

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

class NeverOpenOrClose : public MockDeviceHooks {
 public:
  NeverOpenOrClose() : MockDeviceHooks(Completer()) {}

  void Open(HookInvocation record, uint32_t flags, OpenCallback callback) override {
    ZX_PANIC("open should never be called");
  }
  void Close(HookInvocation record, uint32_t flags, CloseCallback callback) override {
    ZX_PANIC("close should never be called");
  }
};

TEST_F(BasicLifecycleTest, StatDoesntCallOpen) {
  std::unique_ptr<RootMockDevice> root_mock_device;
  std::unique_ptr<MockDevice> mock_child_device;
  fidl::InterfacePtr<fuchsia::io::Node> client;

  auto promise = CreateFirstChild(&root_mock_device, &mock_child_device)
                     .and_then([&]() { return DoWaitForPath(mock_child_device->path()); })
                     .and_then([&]() {
                       mock_child_device->set_hooks(std::make_unique<NeverOpenOrClose>());
                       return DoOpen(mock_child_device->path(), &client,
                                     fuchsia::io::OPEN_FLAG_NODE_REFERENCE);
                     })
                     .and_then([&]() { client.Unbind(); });

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

}  // namespace libdriver_integration_test
