#include "google/google_service_nvme.hpp"

#include <systemd/sd-bus.h>

#include <cstdint>
#include <memory>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT
#include <tuple>
#include <utility>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "absl/functional/any_invocable.h"
#include "boost/asio/post.hpp"  // NOLINT
#include "app.hpp"
#include "http_request.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "test/g3/mock_managed_store.hpp"
#include "test/g3/mock_managed_store_test.hpp"
#include "sdbusplus/message.hpp"
#include "sdbusplus/message/native_types.hpp"
#include "sdbusplus/test/sdbus_mock.hpp"

namespace crow::google_api {
namespace {

using ::managedStore::KeyType;
using ::managedStore::ManagedType;
using ::testing::_;
using ::testing::An;
using ::testing::MakePolymorphicAction;
using ::testing::NiceMock;
using ::testing::PolymorphicAction;
using ::testing::Return;

constexpr std::string_view kNvmeId = "nvme_0";
constexpr std::string_view kControllerId = "controller_0";
constexpr std::string_view kControllerPath =
    "/xyz/openbmc_project/inventory/system/board/nvme_0/controller_0";
constexpr std::string_view kNvmePath =
    "/xyz/openbmc_project/inventory/system/board/nvme_0";

class GoogleServiceNvmeTest : public ::managedStore::MockManagedStoreTest {
 protected:
  GoogleServiceNvmeTest() : app_(true) {
    share_async_resp_ = std::make_shared<bmcweb::AsyncResp>();
  }

  void SetUp() override {
    ::managedStore::MockManagedStoreTest::SetUp();

    // Mock NVMe Controller object
    KeyType nvmeKey(ManagedType::kManagedSubtree,
                    "/xyz/openbmc_project/inventory", 0,
                    {"xyz.openbmc_project.Inventory.Item.Drive"});

    dbus::utility::MapperGetSubTreeResponse subtree = {
        {std::string(kNvmePath),
         {{"xyz.openbmc_project.Inventory.Item.Drive",
           {"xyz.openbmc_project.Inventory.Item.Drive"}}}}};

    EXPECT_TRUE(
        dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
            managedStore::GetManagedObjectStore())
            ->upsertMockObjectIntoManagedStore(
                nvmeKey,
                managedStore::MockManagedStoreTest::CreateValueType(subtree))
            .ok());

    // Mock Drive Protocol
    KeyType protocolKey(ManagedType::kManagedProperty,
                        "xyz.openbmc_project.Inventory.Item.Drive",
                        sdbusplus::message::object_path(std::string(kNvmePath)),
                        "xyz.openbmc_project.Inventory.Item.Drive", "Protocol");

    dbus::utility::DbusVariantType protocolVariant = std::string(
        "xyz.openbmc_project.Inventory.Item.Drive.DriveProtocol.NVMe");
    EXPECT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
                    managedStore::GetManagedObjectStore())
                    ->upsertMockObjectIntoManagedStore(
                        protocolKey,
                        managedStore::MockManagedStoreTest::CreateValueType(
                            protocolVariant))
                    .ok());

    // Mock storage controller association
    KeyType storageControllerKey(
        ManagedType::kManagedProperty, "xyz.openbmc_project.ObjectMapper",
        sdbusplus::message::object_path(std::string(kNvmePath) +
                                        "/storage_controller"),
        "xyz.openbmc_project.Association", "endpoints");

    std::vector<std::string> endpoints = {std::string(kControllerPath)};
    dbus::utility::DbusVariantType endpointsVariant = endpoints;

    EXPECT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
                    managedStore::GetManagedObjectStore())
                    ->upsertMockObjectIntoManagedStore(
                        storageControllerKey,
                        managedStore::MockManagedStoreTest::CreateValueType(
                            endpointsVariant))
                    .ok());

    // Mock Lockdown Interface
    KeyType lockdownKey(ManagedType::kManagedMapperObject,
                        std::string(kControllerPath),
                        {"xyz.openbmc_project.NVMe.Lockdown"});
    dbus::utility::MapperGetObject lockdownObject = {
        {"xyz.openbmc_project.NVMe.Lockdown",
         {{"xyz.openbmc_project.NVMe.Lockdown", {}}}}};

    EXPECT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
                    managedStore::GetManagedObjectStore())
                    ->upsertMockObjectIntoManagedStore(
                        lockdownKey,
                        managedStore::MockManagedStoreTest::CreateValueType(
                            lockdownObject))
                    .ok());
  }

  crow::Request CreateRequest(std::string_view body) {
    std::error_code ec;
    boost::beast::http::request<boost::beast::http::string_body> beastReq;
    beastReq.method(boost::beast::http::verb::post);
    beastReq.target(
        "/google/v1/NVMe/nvme_0/Controllers/controller_0/Actions/"
        "NVMeController.LockdownInband");
    beastReq.set(boost::beast::http::field::content_type, "application/json");
    beastReq.body() = std::string(body);
    beastReq.prepare_payload();
    return crow::Request(beastReq, ec);
  }

  std::shared_ptr<bmcweb::AsyncResp> share_async_resp_;
  App app_;
};

class SimulateSuccessfulAsyncPostDbusCallThreadSafeWithMsgAndValueAction {
  const std::tuple<uint32_t, uint32_t, uint32_t, std::string, uint32_t> value_;

 public:
  explicit SimulateSuccessfulAsyncPostDbusCallThreadSafeWithMsgAndValueAction(
      const std::tuple<uint32_t, uint32_t, uint32_t, std::string, uint32_t>&
          value)
      : value_(value) {}

  template <typename Result, typename ArgumentTuple>
  Result Perform(const ArgumentTuple& args) const {
    auto callback = std::make_shared<absl::AnyInvocable<void(
        const boost::system::error_code&, const sdbusplus::message_t&,
        const std::tuple<uint32_t, uint32_t, uint32_t, std::string,
                         uint32_t>&)>>(
        std::move(std::get<1>(const_cast<ArgumentTuple&>(args))));
    boost::asio::post(
        managedStore::GetManagedObjectStore()->GetIoContext(),
        [callback, val = value_]() mutable {
          // Mock sdbus message
          auto sdbus = std::make_shared<NiceMock<sdbusplus::SdBusMock>>();
          EXPECT_CALL(*sdbus, sd_bus_message_ref(_))
              .WillRepeatedly(Return(nullptr));
          EXPECT_CALL(*sdbus, sd_bus_message_get_error(_))
              .WillRepeatedly(Return(nullptr));

          sdbusplus::message_t msg(nullptr, sdbus.get());

          std::move (*callback)(boost::system::error_code(), msg, val);
        });
  }

  static PolymorphicAction<
      SimulateSuccessfulAsyncPostDbusCallThreadSafeWithMsgAndValueAction>
  SimulateSuccessfulAsyncPostDbusCallWithMsgAndValue(
      const std::tuple<uint32_t, uint32_t, uint32_t, std::string, uint32_t>&
          value) {
    return MakePolymorphicAction(
        SimulateSuccessfulAsyncPostDbusCallThreadSafeWithMsgAndValueAction(
            value));
  }
};

TEST_F(GoogleServiceNvmeTest, LockdownInbandProhibitFalse) {
  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          _,
          An<absl::AnyInvocable<void(
              const boost::system::error_code&, const sdbusplus::message_t&,
              const std::tuple<uint32_t, uint32_t, uint32_t, std::string,
                               uint32_t>&)>&&>(),
          "xyz.openbmc_project.NVMe.Lockdown", std::string(kControllerPath),
          "xyz.openbmc_project.NVMe.Lockdown", "LockdownInband", 0,
          std::vector<uint8_t>{}, std::vector<uint8_t>{},
          std::vector<uint8_t>{}))
      .Times(1)
      .WillOnce(
          SimulateSuccessfulAsyncPostDbusCallThreadSafeWithMsgAndValueAction::
              SimulateSuccessfulAsyncPostDbusCallWithMsgAndValue(
                  std::make_tuple(uint32_t{0}, uint32_t{0}, uint32_t{0},
                                  std::string{""}, uint32_t{0})));

  crow::Request req = CreateRequest(R"({"Prohibit": false})");

  handleGoogleNvmeControllerLockdownInband(app_, req, share_async_resp_,
                                           std::string(kNvmeId),
                                           std::string(kControllerId));

  RunIoUntilDone();

  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(GoogleServiceNvmeTest, LockdownInbandProhibitTrue) {
  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          _,
          An<absl::AnyInvocable<void(
              const boost::system::error_code&, const sdbusplus::message_t&,
              const std::tuple<uint32_t, uint32_t, uint32_t, std::string,
                               uint32_t>&)>&&>(),
          "xyz.openbmc_project.NVMe.Lockdown", std::string(kControllerPath),
          "xyz.openbmc_project.NVMe.Lockdown", "LockdownInband", 1,
          std::vector<uint8_t>{}, std::vector<uint8_t>{},
          std::vector<uint8_t>{}))
      .Times(1)
      .WillOnce(
          SimulateSuccessfulAsyncPostDbusCallThreadSafeWithMsgAndValueAction::
              SimulateSuccessfulAsyncPostDbusCallWithMsgAndValue(
                  std::make_tuple(0, 0, 0, "", 0)));

  crow::Request req = CreateRequest(R"({"Prohibit": true})");

  handleGoogleNvmeControllerLockdownInband(app_, req, share_async_resp_,
                                           std::string(kNvmeId),
                                           std::string(kControllerId));

  RunIoUntilDone();

  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(GoogleServiceNvmeTest, LockdownInbandWithAdminCmds) {
  std::vector<uint8_t> expectedAdminCmds = {0x1, 0x2, 0x3};

  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          _,
          An<absl::AnyInvocable<void(
              const boost::system::error_code&, const sdbusplus::message_t&,
              const std::tuple<uint32_t, uint32_t, uint32_t, std::string,
                               uint32_t>&)>&&>(),
          "xyz.openbmc_project.NVMe.Lockdown", std::string(kControllerPath),
          "xyz.openbmc_project.NVMe.Lockdown", "LockdownInband", 0,
          expectedAdminCmds, std::vector<uint8_t>{}, std::vector<uint8_t>{}))
      .Times(1)
      .WillOnce(
          SimulateSuccessfulAsyncPostDbusCallThreadSafeWithMsgAndValueAction::
              SimulateSuccessfulAsyncPostDbusCallWithMsgAndValue(
                  std::make_tuple(0, 0, 0, "", 0)));

  crow::Request req =
      CreateRequest(R"({"Prohibit": false, "AdminCmds": [1, 2, 3]})");

  handleGoogleNvmeControllerLockdownInband(app_, req, share_async_resp_,
                                           std::string(kNvmeId),
                                           std::string(kControllerId));

  RunIoUntilDone();

  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(GoogleServiceNvmeTest, LockdownInbandAllParams) {
  std::vector<uint8_t> expectedAdminCmds = {0xA};
  std::vector<uint8_t> expectedFeatures = {0xB, 0xC};
  std::vector<uint8_t> expectedLogPages = {0xD};

  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          _,
          An<absl::AnyInvocable<void(
              const boost::system::error_code&, const sdbusplus::message_t&,
              const std::tuple<uint32_t, uint32_t, uint32_t, std::string,
                               uint32_t>&)>&&>(),
          "xyz.openbmc_project.NVMe.Lockdown", std::string(kControllerPath),
          "xyz.openbmc_project.NVMe.Lockdown", "LockdownInband", 1,
          expectedAdminCmds, expectedFeatures, expectedLogPages))
      .Times(1)
      .WillOnce(
          SimulateSuccessfulAsyncPostDbusCallThreadSafeWithMsgAndValueAction::
              SimulateSuccessfulAsyncPostDbusCallWithMsgAndValue(
                  std::make_tuple(0, 0, 0, "", 0)));

  crow::Request req = CreateRequest(
      R"({"Prohibit": true, "AdminCmds": [10], "Features": [11, 12], "LogPages": [13]})");

  handleGoogleNvmeControllerLockdownInband(app_, req, share_async_resp_,
                                           std::string(kNvmeId),
                                           std::string(kControllerId));

  RunIoUntilDone();

  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(GoogleServiceNvmeTest, LockdownInbandDbusError) {
  NiceMock<sdbusplus::SdBusMock> sdbus;
  ::sd_bus_error err = SD_BUS_ERROR_NULL;
  err.name = "org.freedesktop.DBus.Error.Failed";
  err.message = "D-Bus call failed";

  EXPECT_CALL(sdbus, sd_bus_message_get_error(_)).WillRepeatedly(Return(&err));
  EXPECT_CALL(sdbus, sd_bus_message_ref(_)).WillRepeatedly(Return(nullptr));

  sdbusplus::message_t msg(nullptr, &sdbus);

  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          _,
          An<absl::AnyInvocable<void(
              const boost::system::error_code&, const sdbusplus::message_t&,
              const std::tuple<uint32_t, uint32_t, uint32_t, std::string,
                               uint32_t>&)>&&>(),
          _, _, _, _, _, _, _, _))
      .Times(1)
      .WillOnce([msg](auto&&, auto&& callback, auto&&...) mutable {
        auto callback_in = std::make_shared<absl::AnyInvocable<void(
            const boost::system::error_code&, const sdbusplus::message_t&,
            const std::tuple<uint32_t, uint32_t, uint32_t, std::string,
                             uint32_t>&)>>(
            std::forward<decltype(callback)>(callback));
        boost::asio::post(managedStore::GetManagedObjectStore()->GetIoContext(),
                          [callback_in, msg]() mutable {
                            std::move (*callback_in)(
                                boost::system::error_code(), msg, {});
                          });
      });

  crow::Request req = CreateRequest(R"({"Prohibit": false})");

  handleGoogleNvmeControllerLockdownInband(app_, req, share_async_resp_,
                                           std::string(kNvmeId),
                                           std::string(kControllerId));

  RunIoUntilDone();

  EXPECT_EQ(share_async_resp_->res.result(),
            boost::beast::http::status::internal_server_error);
  EXPECT_EQ(share_async_resp_->res.jsonValue["error"]["message"],
            "D-Bus call failed");
}

TEST_F(GoogleServiceNvmeTest, LockdownInbandBoostError) {
  NiceMock<sdbusplus::SdBusMock> sdbus;
  EXPECT_CALL(sdbus, sd_bus_message_get_error(_))
      .WillRepeatedly(Return(nullptr));
  EXPECT_CALL(sdbus, sd_bus_message_ref(_)).WillRepeatedly(Return(nullptr));

  sdbusplus::message_t msg(nullptr, &sdbus);

  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          _,
          An<absl::AnyInvocable<void(
              const boost::system::error_code&, const sdbusplus::message_t&,
              const std::tuple<uint32_t, uint32_t, uint32_t, std::string,
                               uint32_t>&)>&&>(),
          _, _, _, _, _, _, _, _))
      .Times(1)
      .WillOnce([msg](auto&&, auto&& callback, auto&&...) mutable {
        auto callback_in = std::make_shared<absl::AnyInvocable<void(
            const boost::system::error_code&, const sdbusplus::message_t&,
            const std::tuple<uint32_t, uint32_t, uint32_t, std::string,
                             uint32_t>&)>>(
            std::forward<decltype(callback)>(callback));
        boost::asio::post(
            managedStore::GetManagedObjectStore()->GetIoContext(),
            [callback_in, msg]() mutable {
              std::move (*callback_in)(boost::system::errc::make_error_code(
                                           boost::system::errc::not_connected),
                                       msg, {});
            });
      });

  crow::Request req = CreateRequest(R"({"Prohibit": false})");

  handleGoogleNvmeControllerLockdownInband(app_, req, share_async_resp_,
                                           std::string(kNvmeId),
                                           std::string(kControllerId));

  RunIoUntilDone();

  EXPECT_EQ(share_async_resp_->res.result(),
            boost::beast::http::status::internal_server_error);
}

}  // namespace
}  // namespace crow::google_api
