#include "async_resp.hpp"
#include "google/google_service_root.hpp"
#include "http_request.hpp"
#include "nlohmann/json.hpp"
#include "test/redfish-core/lib/snapshot_fixture.hpp"

#include <cstdint>

#include <gtest/gtest.h>

namespace crow::google_api
{
namespace
{

void validateServiceRootGet(crow::Response& res)
{
    nlohmann::json& json = res.jsonValue;
    EXPECT_EQ(json["@odata.id"], "/google/v1");
    EXPECT_EQ(json["@odata.type"],
              "#GoogleServiceRoot.v1_0_0.GoogleServiceRoot");
    EXPECT_EQ(json["@odata.id"], "/google/v1");
    EXPECT_EQ(json["Id"], "Google Rest RootService");
    EXPECT_EQ(json["Name"], "Google Service Root");
    EXPECT_EQ(json["Version"], "1.0.0");
    EXPECT_EQ(json["RootOfTrustCollection"]["@odata.id"],
              "/google/v1/RootOfTrustCollection");
    EXPECT_EQ(json["NVMe"]["@odata.id"], "/google/v1/NVMe");
}

TEST(HandleGoogleV1Get, OnSuccess)
{
    App app(/*allowSessionEmpty=*/true);
    std::error_code ec;
    auto asyncResp = std::make_shared<bmcweb::AsyncResp>();

    asyncResp->res.setCompleteRequestHandler(validateServiceRootGet);

    crow::Request dummyRequest{{boost::beast::http::verb::get, "", 11}, ec};
    handleGoogleV1Get(app, dummyRequest, asyncResp);
}

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

namespace redfish
{
namespace
{

using ::dbus::utility::DBusPropertiesMap;
using managedStore::KeyType;
using managedStore::ManagedType;

TEST_F(SnapshotFixture_Platform11_Config8, HandleRootOfTrustGetCorrectLocation)
{
    crow::google_api::handleRootOfTrustGet(app_, CreateRequest(),
                                           share_async_resp_, "Hoth");
    RunIoUntilDone();

    nlohmann::json& json = share_async_resp_->res.jsonValue;

    EXPECT_EQ(json["@odata.id"], "/google/v1/RootOfTrustCollection/Hoth");
    EXPECT_EQ(json["Location"]["PartLocation"]["LocationType"], "Embedded");
    EXPECT_EQ(json["Location"]["PartLocation"]["ServiceLabel"], "Hoth");
    EXPECT_EQ(json["Location"]["PartLocationContext"], "DC_SCM");
}

TEST_F(SnapshotFixture_Platform11_Config8, HandleRootOfTrustGet)
{
    EXPECT_TRUE(
        dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
            managedStore::GetManagedObjectStore())
            ->upsertMockObjectIntoManagedStore(
                KeyType(ManagedType::kManagedPropertyMap,
                        "xyz.openbmc_project.Control.Hoth",
                        sdbusplus::message::object_path(
                            "/xyz/openbmc_project/Control/Hoth"),
                        "xyz.openbmc_project.Control.Hoth.State"),
                managedStore::MockManagedStoreTest::CreateValueType(
                    DBusPropertiesMap({
                        std::make_pair("BootloaderUpdateFailureCode",
                                       uint32_t{0}),
                        std::make_pair("FirmwareUpdateFailedMinor",
                                       uint32_t{0}),
                        std::make_pair("FirmwareUpdateFailureCode",
                                       uint32_t{4}),
                        std::make_pair("ResetFlags", uint32_t{0}),
                        std::make_pair("RoInfoStrikes", uint32_t{0}),
                        std::make_pair("RwInfoStrikes", uint32_t{0}),
                        std::make_pair("UpTime", uint64_t{19441701616}),
                        std::make_pair("HasPersistentPanicInfo", false),
                        std::make_pair("PayloadConfirmFailureCode",
                                       uint32_t{0}),
                        std::make_pair("PayloadUpdateFailureCode", uint32_t{0}),
                        std::make_pair("HasValidAuthRecord", false),
                        std::make_pair("AuthRecordCapabilities", uint64_t{0}),
                        std::make_pair("SecureBootEnforced", true),

                        std::make_pair("KeyRotationVersion", uint32_t{1}),
                        std::make_pair("KeyRotationImageFamily", uint16_t{2}),
                        std::make_pair("KeyRotationImageFamilyVariant",
                                       uint16_t{3}),
                        std::make_pair("KeyRotationValidationMethod",
                                       uint32_t{4}),
                        std::make_pair("KeyRotationValidationKeyData",
                                       uint32_t{5}),
                        std::make_pair("KeyRotationValidationHashData",
                                       uint32_t{6}),
                    })))
            .ok());

    EXPECT_CALL(
        *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
            managedStore::GetManagedObjectStore()),
        PostDbusCallWithObjectPath(
            testing::_,
            testing::An<absl::AnyInvocable<void(
                const boost::system::error_code&, const std::string&)>&&>(),
            "xyz.openbmc_project.securityd.TpmAttestationService",
            "/xyz/openbmc_project/securityd/tpm_attestation_service",
            "xyz.openbmc_project.securityd.TpmAttestationService",
            "ReadPcrValues",
            sdbusplus::message::object_path(
                "/xyz/openbmc_project/Control/Hoth")))
        .Times(1)
        .WillOnce(
            managedStore::
                SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction<
                    std::string>::
                    SimulateSuccessfulAsyncPostDbusCallWithValue(
                        std::make_shared<std::string>("pcr-values-string")));

    crow::google_api::handleRootOfTrustGet(app_, CreateRequest(),
                                           share_async_resp_, "Hoth");

    RunIoUntilDone();

    nlohmann::json& json = share_async_resp_->res.jsonValue;

    EXPECT_EQ(json["Status"]["Oem"]["BootloaderUpdateFailureCode"], 0);
    EXPECT_EQ(json["Status"]["Oem"]["FirmwareUpdateFailedMinor"], 0);
    EXPECT_EQ(json["Status"]["Oem"]["FirmwareUpdateFailureCode"], 4);
    EXPECT_EQ(json["Status"]["Oem"]["ResetFlags"], 0);
    EXPECT_EQ(json["Status"]["Oem"]["RoInfoStrikes"], 0);
    EXPECT_EQ(json["Status"]["Oem"]["RwInfoStrikes"], 0);
    EXPECT_EQ(json["Status"]["Oem"]["UpTime"], 19441701616);
    EXPECT_EQ(json["Status"]["Oem"]["HasPersistentPanicInfo"], false);
    EXPECT_EQ(json["Status"]["Oem"]["Payload"]["ConfirmFailureCode"], 0);
    EXPECT_EQ(json["Status"]["Oem"]["Payload"]["UpdateFailureCode"], 0);
    EXPECT_EQ(json["Status"]["Oem"]["Authorization"]["Valid"], false);
    EXPECT_EQ(json["Status"]["Oem"]["Authorization"]["Capabilities"], 0);
    EXPECT_EQ(json["Status"]["Oem"]["SecureBootEnforced"], true);

    EXPECT_EQ(json["Status"]["Oem"]["KeyRotation"]["Version"], 1);
    EXPECT_EQ(json["Status"]["Oem"]["KeyRotation"]["ImageFamily"], 2);
    EXPECT_EQ(json["Status"]["Oem"]["KeyRotation"]["ImageFamilyVariant"], 3);
    EXPECT_EQ(json["Status"]["Oem"]["KeyRotation"]["ValidationMethod"], 4);
    EXPECT_EQ(json["Status"]["Oem"]["KeyRotation"]["ValidationKeyData"], 5);
    EXPECT_EQ(json["Status"]["Oem"]["KeyRotation"]["ValidationHashData"], 6);

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

TEST_F(SnapshotFixture_Platform11_Config8, HandleGetSignedMeasurementsPost)
{
    nlohmann::json requestJson;
    requestJson["Nonce"] = "0123456789ABCDEF";
    requestJson["PCRSelection"] = "pcrSelectionBase64";

    // Include SHA 256 hash of input nonce
    EXPECT_CALL(
        *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
            managedStore::GetManagedObjectStore()),
        PostDbusCallWithObjectPathAndTwoStrings(
            testing::_,
            testing::An<absl::AnyInvocable<void(
                const boost::system::error_code&, const std::string&)>&&>(),
            "xyz.openbmc_project.securityd.TpmAttestationService",
            "/xyz/openbmc_project/securityd/tpm_attestation_service",
            "xyz.openbmc_project.securityd.TpmAttestationService",
            "GetPcrQuote",
            sdbusplus::message::object_path(
                "/xyz/openbmc_project/Control/Hoth"),
            "pcrSelectionBase64", testing::_))
        .Times(1)
        .WillOnce(
            managedStore::
                SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction<
                    std::string>::
                    SimulateSuccessfulAsyncPostDbusCallWithValue(
                        std::make_shared<std::string>("quote-string")));

    crow::google_api::handleGetSignedMeasurementsPost(
        app_, CreateRequest(requestJson.dump()), share_async_resp_, "Hoth");

    RunIoUntilDone();

    nlohmann::json& json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["SignedMeasurements"], "quote-string");
    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(SnapshotFixture_Platform11_Config8, HandleRootOfTrustCertificatesGet)
{
    EXPECT_CALL(
        *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
            managedStore::GetManagedObjectStore()),
        PostDbusCallWithObjectPath(
            testing::_,
            testing::An<absl::AnyInvocable<void(
                const boost::system::error_code&, const std::string&)>&&>(),
            "xyz.openbmc_project.securityd.TpmAttestationService",
            "/xyz/openbmc_project/securityd/tpm_attestation_service",
            "xyz.openbmc_project.securityd.TpmAttestationService",
            "GetEkCertChain",
            sdbusplus::message::object_path(
                "/xyz/openbmc_project/Control/Hoth")))
        .Times(1)
        .WillOnce(
            managedStore::
                SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction<
                    std::string>::
                    SimulateSuccessfulAsyncPostDbusCallWithValue(
                        std::make_shared<std::string>("cert-chain-string")));

    crow::google_api::handleRootOfTrustCertificatesGet(
        app_, CreateRequest(), share_async_resp_, "Hoth");

    RunIoUntilDone();

    nlohmann::json& json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["@odata.type"], "#Certificate.v1_0_0.Certificate");
    EXPECT_EQ(json["@odata.id"],
              "/google/v1/RootOfTrustCollection/Hoth/Certificates");
    EXPECT_EQ(json["Id"], "Certificates");
    EXPECT_EQ(json["Name"], "Root Of Trust Certificates");
    EXPECT_EQ(json["CertUsageTypes"], nlohmann::json::array({"Device"}));
    EXPECT_EQ(json["CertificateType"], "DICE_FEK");
    EXPECT_EQ(json["CertString"], "cert-chain-string");
    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(SnapshotFixture_Platform11_Config8,
       HandleRootOfTrustCertificatesGetRoTNotFound)
{
    crow::google_api::handleRootOfTrustCertificatesGet(
        app_, CreateRequest(), share_async_resp_, "NonExistentHoth");

    RunIoUntilDone();

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

TEST_F(SnapshotFixture_Platform11_Config8,
       HandleGetSignedMeasurementsPostMissingNonce)
{
    nlohmann::json requestJson;
    requestJson["PCRSelection"] = "pcrSelectionBase64";

    crow::google_api::handleGetSignedMeasurementsPost(
        app_, CreateRequest(requestJson.dump()), share_async_resp_, "Hoth");

    RunIoUntilDone();

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

TEST_F(SnapshotFixture_Platform11_Config8,
       HandleGetSignedMeasurementsPostMissingPCRSelection)
{
    nlohmann::json requestJson;
    requestJson["Nonce"] = "0123456789ABCDEF";

    crow::google_api::handleGetSignedMeasurementsPost(
        app_, CreateRequest(requestJson.dump()), share_async_resp_, "Hoth");

    RunIoUntilDone();

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

TEST_F(SnapshotFixture_Platform11_Config8,
       HandleGetSignedMeasurementsPostRoTNotFound)
{
    nlohmann::json requestJson;
    requestJson["Nonce"] = "0123456789ABCDEF";
    requestJson["PCRSelection"] = "pcrSelectionBase64";

    crow::google_api::handleGetSignedMeasurementsPost(
        app_, CreateRequest(requestJson.dump()), share_async_resp_,
        "NonExistentHoth");

    RunIoUntilDone();

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

} // namespace
} // namespace redfish
