// Copyright 2018 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.

#ifndef SRC_DEVICES_TESTS_LIBDRIVER_INTEGRATION_TEST_MOCK_DEVICE_HOOKS_H_
#define SRC_DEVICES_TESTS_LIBDRIVER_INTEGRATION_TEST_MOCK_DEVICE_HOOKS_H_

#include <fuchsia/device/mock/cpp/fidl.h>
#include <lib/fidl/coding.h>
#include <lib/fit/function.h>
#include <lib/fpromise/bridge.h>
#include <lib/zx/channel.h>

#include <string>
#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include "action-list.h"

namespace libdriver_integration_test {

// Base class of the hook hierarchy.  It provides default implementations that
// will return errors if invoked.
class MockDeviceHooks : public fuchsia::device::mock::MockDevice {
 public:
  using Completer = fpromise::completer<void, std::string>;
  explicit MockDeviceHooks(Completer completer);

  using HookInvocation = fuchsia::device::mock::HookInvocation;
  void Bind(HookInvocation record, BindCallback callback) override { Fail(__FUNCTION__); }

  void Release(HookInvocation record) override { Fail(__FUNCTION__); }

  void GetProtocol(HookInvocation record, uint32_t protocol_id,
                   GetProtocolCallback callback) override {
    Fail(__FUNCTION__);
  }

  void Open(HookInvocation record, uint32_t flags, OpenCallback callback) override {
    Fail(__FUNCTION__);
  }

  void Close(HookInvocation record, uint32_t flags, CloseCallback callback) override {
    Fail(__FUNCTION__);
  }

  void Unbind(HookInvocation record, UnbindCallback callback) override { Fail(__FUNCTION__); }

  void Read(HookInvocation record, uint64_t count, zx_off_t off, ReadCallback callback) override {
    Fail(__FUNCTION__);
  }

  void Write(HookInvocation record, std::vector<uint8_t> buffer, zx_off_t off,
             WriteCallback callback) override {
    Fail(__FUNCTION__);
  }

  void GetSize(HookInvocation record, GetSizeCallback callback) override { Fail(__FUNCTION__); }

  void Suspend(HookInvocation record, uint8_t requested_state, bool enable_wake,
               uint8_t suspend_reason, SuspendCallback callback) override {
    Fail(__FUNCTION__);
  }

  void Resume(HookInvocation record, uint32_t requested_state, ResumeCallback callback) override {
    Fail(__FUNCTION__);
  }

  void Message(HookInvocation record, MessageCallback callback) override { Fail(__FUNCTION__); }

  void Rxrpc(HookInvocation record, RxrpcCallback callback) override { Fail(__FUNCTION__); }

  void AddDeviceDone(uint64_t action_id) final { ZX_ASSERT(false); }
  void UnbindReplyDone(uint64_t action_id) final { ZX_ASSERT(false); }
  void SuspendReplyDone(uint64_t action_id) final { ZX_ASSERT(false); }
  void ResumeReplyDone(uint64_t action_id) final { ZX_ASSERT(false); }

  virtual ~MockDeviceHooks() = default;

  void Fail(const char* function) {
    std::string message("Unexpected ");
    message.append(function);
    ADD_FAILURE() << message;
    if (completer_) {
      completer_.complete_error(std::move(message));
    }
  }

  void set_action_list_finalizer(
      fit::function<std::vector<ActionList::Action>(ActionList)> finalizer) {
    action_list_finalizer_ = std::move(finalizer);
  }

 protected:
  Completer completer_;
  fit::function<std::vector<ActionList::Action>(ActionList)> action_list_finalizer_;
};

class BindOnce : public MockDeviceHooks {
 public:
  using Callback = fit::function<ActionList(HookInvocation, Completer)>;

  BindOnce(Completer completer, Callback callback)
      : MockDeviceHooks(std::move(completer)), callback_(std::move(callback)) {}
  virtual ~BindOnce() = default;

  void Bind(HookInvocation record, BindCallback callback) override {
    if (!completer_) {
      return Fail(__FUNCTION__);
    }
    callback(action_list_finalizer_(callback_(record, std::move(completer_))));
  }

 private:
  Callback callback_;
};

class UnbindOnce : public MockDeviceHooks {
 public:
  using Callback = fit::function<ActionList(HookInvocation, Completer)>;

  UnbindOnce(Completer completer, Callback callback)
      : MockDeviceHooks(std::move(completer)), callback_(std::move(callback)) {}
  virtual ~UnbindOnce() = default;

  void Unbind(HookInvocation record, UnbindCallback callback) override {
    if (!completer_) {
      return Fail(__FUNCTION__);
    }
    callback(action_list_finalizer_(callback_(record, std::move(completer_))));
  }

 private:
  Callback callback_;
};

class OpenOnce : public MockDeviceHooks {
 public:
  using Callback = fit::function<ActionList(HookInvocation, uint32_t, Completer)>;

  OpenOnce(Completer completer, Callback callback)
      : MockDeviceHooks(std::move(completer)), callback_(std::move(callback)) {}
  virtual ~OpenOnce() = default;

  void Open(HookInvocation record, uint32_t flags, OpenCallback callback) override {
    if (!completer_) {
      return Fail(__FUNCTION__);
    }
    callback(action_list_finalizer_(callback_(record, flags, std::move(completer_))));
  }

 private:
  Callback callback_;
};

class CloseOnce : public MockDeviceHooks {
 public:
  using Callback = fit::function<ActionList(HookInvocation, uint32_t, Completer)>;

  CloseOnce(Completer completer, Callback callback)
      : MockDeviceHooks(std::move(completer)), callback_(std::move(callback)) {}
  virtual ~CloseOnce() = default;

  void Close(HookInvocation record, uint32_t flags, CloseCallback callback) override {
    if (!completer_) {
      return Fail(__FUNCTION__);
    }
    callback(action_list_finalizer_(callback_(record, flags, std::move(completer_))));
  }

 private:
  Callback callback_;
};

class ReleaseOnce : public MockDeviceHooks {
 public:
  using Callback = fit::function<void(HookInvocation, Completer)>;

  ReleaseOnce(Completer completer, Callback callback)
      : MockDeviceHooks(std::move(completer)), callback_(std::move(callback)) {}
  virtual ~ReleaseOnce() = default;

  void Release(HookInvocation record) override {
    if (!completer_) {
      return Fail(__FUNCTION__);
    }
    callback_(record, std::move(completer_));
  }

 private:
  Callback callback_;
};

// Class for expecting a sequence of hooks in any order (each once)
class UnorderedHooks : public MockDeviceHooks {
 public:
  // Construct a set of hooks that will complete |completer| after they all
  // run.
  explicit UnorderedHooks(Completer completer) : MockDeviceHooks(std::move(completer)) {}
  virtual ~UnorderedHooks() = default;

  void Bind(HookInvocation record, BindCallback callback) override;
  void Release(HookInvocation record) override;
  void GetProtocol(HookInvocation record, uint32_t protocol_id,
                   GetProtocolCallback callback) override;
  void Open(HookInvocation record, uint32_t flags, OpenCallback callback) override;
  void Close(HookInvocation record, uint32_t flags, CloseCallback callback) override;
  void Unbind(HookInvocation record, UnbindCallback callback) override;
  void Read(HookInvocation record, uint64_t count, zx_off_t off, ReadCallback callback) override;
  void Write(HookInvocation record, std::vector<uint8_t> buffer, zx_off_t off,
             WriteCallback callback) override;
  void GetSize(HookInvocation record, GetSizeCallback callback) override;
  void Suspend(HookInvocation record, uint8_t requested_state, bool enable_wake,
               uint8_t suspend_reason, SuspendCallback callback) override;
  void Resume(HookInvocation record, uint32_t flags, ResumeCallback callback) override;
  void Message(HookInvocation record, MessageCallback callback) override;
  void Rxrpc(HookInvocation record, RxrpcCallback callback) override;

 private:
  // Check if all of the hooks have been run, and if so complete the
  // completer.
  void TryFinish();

  fit::function<ActionList(HookInvocation)> bind_;
  fit::function<void(HookInvocation)> release_;
  fit::function<ActionList(HookInvocation, uint32_t)> get_protocol_;
  fit::function<ActionList(HookInvocation, uint32_t)> open_;
  fit::function<ActionList(HookInvocation, std::string, uint32_t)> open_at_;
  fit::function<ActionList(HookInvocation, uint32_t)> close_;
  fit::function<ActionList(HookInvocation)> unbind_;
  fit::function<ActionList(HookInvocation, uint64_t, zx_off_t)> read_;
  fit::function<ActionList(HookInvocation, std::vector<uint8_t>, zx_off_t)> write_;
  fit::function<ActionList(HookInvocation)> get_size_;
  fit::function<ActionList(HookInvocation, uint8_t requested_state, bool enable_wake,
                           uint8_t suspend_reason)>
      suspend_;
  fit::function<ActionList(HookInvocation, uint32_t)> resume_;
  fit::function<ActionList(HookInvocation)> message_;
  fit::function<ActionList(HookInvocation)> rxrpc_;

 public:
  void set_bind(decltype(bind_) hook) { bind_ = std::move(hook); }
  void set_release(decltype(release_) hook) { release_ = std::move(hook); }
  void set_get_protocol(decltype(get_protocol_) hook) { get_protocol_ = std::move(hook); }
  void set_open(decltype(open_) hook) { open_ = std::move(hook); }
  void set_open_at(decltype(open_at_) hook) { open_at_ = std::move(hook); }
  void set_close(decltype(close_) hook) { close_ = std::move(hook); }
  void set_unbind(decltype(unbind_) hook) { unbind_ = std::move(hook); }
  void set_read(decltype(read_) hook) { read_ = std::move(hook); }
  void set_write(decltype(write_) hook) { write_ = std::move(hook); }
  void set_get_size(decltype(get_size_) hook) { get_size_ = std::move(hook); }
  void set_suspend(decltype(suspend_) hook) { suspend_ = std::move(hook); }
  void set_resume(decltype(resume_) hook) { resume_ = std::move(hook); }
  void set_message(decltype(message_) hook) { message_ = std::move(hook); }
  void set_rxrpc(decltype(rxrpc_) hook) { rxrpc_ = std::move(hook); }
};

class IgnoreGetProtocol : public MockDeviceHooks {
 public:
  explicit IgnoreGetProtocol() : MockDeviceHooks({}) {}
  virtual ~IgnoreGetProtocol() = default;

  void GetProtocol(HookInvocation record, uint32_t proto, GetProtocolCallback callback) override {
    ActionList actions;
    actions.AppendReturnStatus(ZX_ERR_NOT_SUPPORTED);
    callback(action_list_finalizer_(std::move(actions)));
  }

 private:
};

}  // namespace libdriver_integration_test

#endif  // SRC_DEVICES_TESTS_LIBDRIVER_INTEGRATION_TEST_MOCK_DEVICE_HOOKS_H_
