// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "CommonTypes.h"
#include "Tss2Wrapper.h"
#include "TpmMocks.h"

using ::testing::_;
using ::testing::DoAll;
using ::testing::Mock;
using ::testing::Return;
using ::testing::SetArgPointee;

std::shared_ptr<TpmLibMock> tpmLibMockObj;

TEST(TestCaseName, TestName) {
  EXPECT_EQ(1, 1);
  EXPECT_TRUE(true);
}

class Tss2WrapperTest : public ::testing::Test {
protected:
    std::unique_ptr<Tss2Wrapper> tss2Wrapper;

    void SetUp() override {
        tss2Wrapper = std::make_unique<Tss2Wrapper>();
        tpmLibMockObj = std::make_shared<TpmLibMock>();
    }

    // Runs after each test case
    void TearDown() override
    {
        EXPECT_TRUE(Mock::VerifyAndClearExpectations(tpmLibMockObj.get()));
        tss2Wrapper.reset();
        tpmLibMockObj.reset();
    }
};

TEST_F(Tss2WrapperTest, ConstructorTest) {
    // Test that the constructor initializes the TssWrapper object
    ASSERT_NE(tss2Wrapper, nullptr);
}

TEST_F(Tss2WrapperTest, Tss2RsaDecryptTest) {
    EXPECT_CALL(*tpmLibMockObj, Tss2_Sys_RSA_Decrypt(_, _, _, _, _, _, _, _))
        .Times(1)
        .WillOnce(Return(TSS2_RC_SUCCESS));
    // Test the Tss2RsaDecrypt method
    std::vector<unsigned char> encryptedData = { 0x01, 0x02, 0x03, 0x04 };
    std::vector<unsigned char> decryptedData = tss2Wrapper->Tss2RsaDecrypt(encryptedData, RsaPaddingScheme::Rsaes);

}

// Verify that RSAES padding passes TPM2_ALG_RSAES to Tss2_Sys_RSA_Decrypt
TEST_F(Tss2WrapperTest, Tss2RsaDecrypt_RsaesPadding_PassesCorrectAlg) {
    EXPECT_CALL(*tpmLibMockObj, Tss2_Sys_RSA_Decrypt(_, _, _, _,
        ::testing::Pointee(::testing::Field(&TPMT_RSA_DECRYPT::scheme,
            TPM2_ALG_RSAES)),
        _, _, _))
        .Times(1)
        .WillOnce(Return(TSS2_RC_SUCCESS));

    std::vector<unsigned char> data = { 0x01, 0x02, 0x03, 0x04 };
    tss2Wrapper->Tss2RsaDecrypt(data, RsaPaddingScheme::Rsaes);
}

// Verify that OAEP padding passes TPM2_ALG_OAEP to Tss2_Sys_RSA_Decrypt
TEST_F(Tss2WrapperTest, Tss2RsaDecrypt_OaepPadding_PassesCorrectAlg) {
    EXPECT_CALL(*tpmLibMockObj, Tss2_Sys_RSA_Decrypt(_, _, _, _,
        ::testing::Pointee(::testing::Field(&TPMT_RSA_DECRYPT::scheme,
            TPM2_ALG_OAEP)),
        _, _, _))
        .Times(1)
        .WillOnce(Return(TSS2_RC_SUCCESS));

    std::vector<unsigned char> data = { 0x01, 0x02, 0x03, 0x04 };
    tss2Wrapper->Tss2RsaDecrypt(data, RsaPaddingScheme::RsaesOaep);
}
