#include "absl/cleanup/cleanup.h"
#include "absl/log/log.h"
#include "bmcweb_config.h"

#include "app.hpp"
#include "async_resp.hpp"
#include "bios.hpp"
#include "http_response.hpp"
#include "nlohmann/json.hpp"
#include "snapshot_fixture.hpp"

#include <boost/system/error_code.hpp>

#include <filesystem>
#include <fstream>
#include <memory>
#include <optional>
#include <vector>

#include <gmock/gmock.h> // IWYU pragma: keep
#include <gtest/gtest.h> // IWYU pragma: keep

// IWYU pragma: no_include <gtest/gtest-message.h>
// IWYU pragma: no_include <gtest/gtest-test-part.h>
// IWYU pragma: no_include "gtest/gtest_pred_impl.h"
// IWYU pragma: no_include <gmock/gmock-matchers.h>
// IWYU pragma: no_include <gtest/gtest-matchers.h>

namespace redfish
{
namespace
{

using ::dbus::utility::DbusVariantType;
using ::managedStore::KeyType;
using ::managedStore::ManagedObjectStoreContext;
using ::managedStore::ManagedType;
using ::managedStore::SimulateFailedAsyncPostDbusCallThreadSafeAction;
using ::managedStore::SimulateSuccessfulAsyncPostDbusCallThreadSafeAction;
using ::managedStore::ValueType;
using ::testing::_;
using ::testing::An;

TEST(ResourceIdFromNameString, ResourceIdFromNameString)
{
    EXPECT_EQ(resourceIdFromNameString("system10"), "10");
}

TEST_F(SnapshotFixture,
       SingleHostPlatformHandleBiosServiceGetTestReturnsCorrectResponse)
{
    handleBiosServiceGet(app_, CreateRequest(), share_async_resp_, "system");

    RunIoUntilDone();

    nlohmann::json& json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["@odata.id"], "/redfish/v1/Systems/system/Bios");
    EXPECT_EQ(json["@odata.type"], "#Bios.v1_1_0.Bios");
    EXPECT_EQ(json["Actions"]["#Bios.ResetBios"]["target"],
              "/redfish/v1/Systems/system/Bios/Actions/Bios.ResetBios");
    EXPECT_EQ(json["Description"], "BIOS Configuration Service");
    EXPECT_EQ(json["Id"], "BIOS");
    EXPECT_EQ(json["Links"]["ActiveSoftwareImage"]["@odata.id"],
              "/redfish/v1/UpdateService/FirmwareInventory/bios_active");

    EXPECT_TRUE(json["Links"]["SoftwareImages"].is_array());
    EXPECT_EQ(json["Links"]["SoftwareImages"].size(), 1);
    EXPECT_EQ(json["Links"]["SoftwareImages"][0]["@odata.id"],
              "/redfish/v1/UpdateService/FirmwareInventory/bios_active");
    EXPECT_EQ(json["Links"]["SoftwareImages@odata.count"], 1);
    EXPECT_EQ(json["Name"], "BIOS Configuration");
    EXPECT_EQ(json["Oem"]["Google"]["MemTestBlob"], "");

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

TEST_F(SnapshotFixture,
       SingleHostPlatformHandleBiosServiceGetTestReturnsNotFound)
{
    handleBiosServiceGet(app_, CreateRequest(), share_async_resp_, "system1");

    RunIoUntilDone();

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

TEST_F(SnapshotFixture,
       SingleHostPlatformHandleBiosServiceGetSystemSubTreePathsResponseError)
{
    // Looking for
    // kManagedSubtreePaths|/|0|xyz.openbmc_project.Inventory.Item.System
    KeyType key(ManagedType::kManagedSubtreePaths, "/", 0,
                {"xyz.openbmc_project.Inventory.Item.System"});

    absl::StatusOr<std::shared_ptr<ValueType>> systemObjectsPathsStatusOr =
        managedStore::GetManagedObjectStore()->getMockObjectFromManagedStore(
            key);
    ASSERT_TRUE(systemObjectsPathsStatusOr.ok());

    // TODO(b/416746677): Uncomment until the bug fixed
    // ASSERT_EQ(systemObjectsPathsStatusOr.value()->managedType,
    //           ManagedType::kManagedSubtreePaths);

    std::optional<dbus::utility::MapperGetSubTreePathsResponse>
        originalSystemObjectsPaths =
            systemObjectsPathsStatusOr.value()->managedSubtreePaths;

    ASSERT_TRUE(originalSystemObjectsPaths.has_value());

    ASSERT_TRUE(
        managedStore::GetManagedObjectStore()
            ->upsertMockObjectIntoManagedStore(
                key, managedStore::MockManagedStoreTest::CreateErrorValueType(
                         originalSystemObjectsPaths.value(),
                         boost::system::errc::make_error_code(
                             boost::system::errc::io_error)))
            .ok());

    absl::Cleanup mockManagedStoreResetter = [key,
                                              originalSystemObjectsPaths]() {
        ASSERT_TRUE(
            managedStore::GetManagedObjectStore()
                ->upsertMockObjectIntoManagedStore(
                    key, managedStore::MockManagedStoreTest::CreateValueType(
                             originalSystemObjectsPaths.value()))
                .ok());
    };

    handleBiosServiceGet(app_, CreateRequest(), share_async_resp_, "system");

    RunIoUntilDone();

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

class SingleHostBiosBlobPatchTest : public SnapshotFixture
{
  protected:
    static void createEmptyBlobFile()
    {
        if (std::filesystem::exists(biosSettingFilePath))
        {
            // remove file if already exists
            std::error_code ec;
            std::filesystem::remove(biosSettingFilePath, ec);
            if (ec)
            {
                LOG(ERROR) << "BIOS setting blob file " << biosSettingFilePath
                           << " exists, failed to remove: " << ec.message();
                FAIL();
            }
        }
        // create a emtpy file to start
        std::ofstream out(biosSettingFilePath);
        out.close();
    }

    static void SetUpTestSuite()
    {
        SnapshotFixture::SetUpTestSuite();
        biosSettingFilepathFromConfig = biosSettingFilePath;
    }

    static void TearDownTestSuite()
    {
        SnapshotFixture::TearDownTestSuite();
        std::error_code ec;
        std::filesystem::remove(biosSettingFilePath, ec);
        if (ec)
        {
            LOG(WARNING) << "Failed to remove BIOS setting blob file "
                         << biosSettingFilePath
                         << " in TearDownTestSuite():" << ec.message();
        }
    }

    void TearDown() override
    {
        std::error_code ec;
        std::filesystem::remove(biosSettingFilePath, ec);
        if (ec)
        {
            LOG(WARNING) << "Failed to remove BIOS setting blob file "
                         << biosSettingFilePath
                         << " in TearDown():" << ec.message();
        }
    }

    static inline const std::string biosSettingFilePath =
        "/run/oem_bios_setting";
};

TEST_F(SingleHostBiosBlobPatchTest, PatchBiosSettingsPeerNotAuthenticated)
{

    // no BIOS setting file if createEmptyBlobFile() is not called
    crow::Request req =
        CreateRequest("{\"Oem\": {\"Google\": {\"MemTestBlob\" : \"AAEC\"}}}");
    // peer_authenticated to false
    req.peer_authenticated = false;

    patchBiosSettings(app_, req, share_async_resp_, "system");
    RunIoUntilDone();

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

TEST_F(SingleHostBiosBlobPatchTest, PatchBiosSettingsRequestNoProperArgument)
{
    // no BIOS setting file if createEmptyBlobFile() is not called
    crow::Request req = CreateRequest("{\"Whatever\": {\"AAEC\"}}}");
    // peer is authenticated
    req.peer_authenticated = true;

    patchBiosSettings(app_, req, share_async_resp_, "system");
    RunIoUntilDone();

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

TEST_F(SingleHostBiosBlobPatchTest, PatchBiosSettingsToNonExistSystem)
{
    // no BIOS setting file if createEmptyBlobFile() is not called
    crow::Request req =
        CreateRequest("{\"Oem\": {\"Google\": {\"MemTestBlob\" : \"AAEC\"}}}");
    // peer is authenticated
    req.peer_authenticated = true;

    patchBiosSettings(app_, req, share_async_resp_, "system1");
    RunIoUntilDone();

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

TEST_F(SingleHostBiosBlobPatchTest, PatchBiosSettingsBlobFileNotExist)
{
    biosSettingFilepathFromConfig = "/non_exist/oem_bios_setting";

    absl::Cleanup bioSettingFilePathResetter = []() {
        biosSettingFilepathFromConfig = biosSettingFilePath;
    };

    // no BIOS setting file if createEmptyBlobFile() is not called
    crow::Request req =
        CreateRequest("{\"Oem\": {\"Google\": {\"MemTestBlob\" : \"AAEC\"}}}");
    // peer is authenticated
    req.peer_authenticated = true;

    patchBiosSettings(app_, req, share_async_resp_, "system");
    RunIoUntilDone();

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

TEST_F(SingleHostBiosBlobPatchTest, PatchBiosSettingsWithNullBlob)
{

    // no BIOS setting file if createEmptyBlobFile() is not called
    crow::Request req =
        CreateRequest("{\"Oem\": {\"Google\": {\"MemTestBlob\" : \"\"}}}");
    // peer is authenticated
    req.peer_authenticated = true;

    handleBiosSettingPatch(share_async_resp_, biosSettingFilepathFromConfig,
                           false, std::nullopt);

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

TEST_F(SingleHostBiosBlobPatchTest, PatchBiosSettingsWithInvalidBlob)
{

    // no BIOS setting file if createEmptyBlobFile() is not called
    // ABCDE= is a invalid base64 encoded string
    crow::Request req = CreateRequest(
        "{\"Oem\": {\"Google\": {\"MemTestBlob\" : \"ABCDE=\"}}}");
    // peer is authenticated
    req.peer_authenticated = true;

    patchBiosSettings(app_, req, share_async_resp_, "system");
    RunIoUntilDone();

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

TEST_F(SingleHostBiosBlobPatchTest,
       PatchBiosSettingsGetSystemSubTreePathsResponseError)
{
    // prepare the BIOS setting file
    createEmptyBlobFile();

    // Looking for
    // kManagedSubtreePaths|/|0|xyz.openbmc_project.Inventory.Item.System
    KeyType key(ManagedType::kManagedSubtreePaths, "/", 0,
                {"xyz.openbmc_project.Inventory.Item.System"});

    absl::StatusOr<std::shared_ptr<ValueType>> systemObjectsPathsStatusOr =
        managedStore::GetManagedObjectStore()->getMockObjectFromManagedStore(
            key);
    ASSERT_TRUE(systemObjectsPathsStatusOr.ok());

    // TODO(b/416746677): Uncomment until the bug fixed
    // ASSERT_EQ(systemObjectsPathsStatusOr.value()->managedType,
    //           ManagedType::kManagedSubtreePaths);

    std::optional<dbus::utility::MapperGetSubTreePathsResponse>
        originalSystemObjectsPaths =
            systemObjectsPathsStatusOr.value()->managedSubtreePaths;

    ASSERT_TRUE(originalSystemObjectsPaths.has_value());

    ASSERT_TRUE(
        managedStore::GetManagedObjectStore()
            ->upsertMockObjectIntoManagedStore(
                key, managedStore::MockManagedStoreTest::CreateErrorValueType(
                         originalSystemObjectsPaths.value(),
                         boost::system::errc::make_error_code(
                             boost::system::errc::io_error)))
            .ok());

    absl::Cleanup mockManagedStoreResetter = [key,
                                              originalSystemObjectsPaths]() {
        ASSERT_TRUE(
            managedStore::GetManagedObjectStore()
                ->upsertMockObjectIntoManagedStore(
                    key, managedStore::MockManagedStoreTest::CreateValueType(
                             originalSystemObjectsPaths.value()))
                .ok());
    };

    crow::Request req =
        CreateRequest("{\"Oem\": {\"Google\": {\"MemTestBlob\" : \"AAEC\"}}}");
    // set authenticated to true
    req.peer_authenticated = true;

    patchBiosSettings(app_, req, share_async_resp_, "system");
    RunIoUntilDone();

    // PATCH request use no_content as convention to indicate a success
    EXPECT_EQ(share_async_resp_->res.result(),
              boost::beast::http::status::internal_server_error);
}

TEST_F(SingleHostBiosBlobPatchTest, PatchBiosSettingsSuccessfully)
{
    crow::Logger::setLogLevel(crow::LogLevel::Error);

    // prepare the BIOS setting file
    createEmptyBlobFile();

    handleBiosServiceGet(app_, CreateRequest(), share_async_resp_, "system");

    RunIoUntilDone();
    nlohmann::json& json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["Oem"]["Google"]["MemTestBlob"], "");
    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);

    if (std::filesystem::exists(biosSettingFilePath))
    {
        LOG(INFO) << biosSettingFilePath << " exists in test body";
    }

    share_async_resp_->res.clear();

    crow::Request req =
        CreateRequest("{\"Oem\": {\"Google\": {\"MemTestBlob\" : \"AAEC\"}}}");
    // set authenticated to true
    req.peer_authenticated = true;

    patchBiosSettings(app_, req, share_async_resp_, "system");
    RunIoUntilDone();

    // PATCH request use no_content as convention to indicate a success
    EXPECT_EQ(share_async_resp_->res.result(),
              boost::beast::http::status::no_content);

    share_async_resp_->res.clear();
    handleBiosServiceGet(app_, CreateRequest(), share_async_resp_, "system");

    RunIoUntilDone();

    json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["Oem"]["Google"]["MemTestBlob"], "AAEC");
    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

} // namespace
} // namespace redfish
