#include "common/instance_id.hpp"
#include "common/utils.hpp"
#include "libpldmresponder/base.hpp"
#include "test/test_instance_id.hpp"

#include <libpldm/base.h>
#include <libpldm/edac.h>

#include <sdeventplus/event.hpp>

#include <algorithm>
#include <array>
#include <cstring>
#include <map>
#include <vector>

#include <gtest/gtest.h>

using namespace pldm::responder;

class TestBaseCommands : public testing::Test
{
  protected:
    TestBaseCommands() : event(sdeventplus::Event::get_default()) {}

    sdeventplus::Event event;
};

TEST_F(TestBaseCommands, testPLDMTypesGoodRequest)
{
    std::array<uint8_t, sizeof(pldm_msg_hdr)> requestPayload{};
    auto request = new (requestPayload.data()) pldm_msg;
    // payload length will be 0 in this case
    size_t requestPayloadLength = 0;
    base::Handler handler(event);
    auto response = handler.getPLDMTypes(request, requestPayloadLength);
    // Need to support OEM type.
    auto responsePtr = new (response.data()) pldm_msg;
    uint8_t* payload_ptr = responsePtr->payload;
    ASSERT_EQ(payload_ptr[0], 0);
    ASSERT_EQ(payload_ptr[1], 157); // 0b10011101 see DSP0240 table11
    ASSERT_EQ(payload_ptr[2], 0);
}

TEST_F(TestBaseCommands, testGetPLDMCommandsGoodRequest)
{
    // Need to support OEM type commands.
    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_REQ_BYTES>
        requestPayload{};
    auto request = new (requestPayload.data()) pldm_msg;
    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
    base::Handler handler(event);
    auto response = handler.getPLDMCommands(request, requestPayloadLength);
    auto responsePtr = new (response.data()) pldm_msg;
    uint8_t* payload_ptr = responsePtr->payload;
    ASSERT_EQ(payload_ptr[0], 0);
    ASSERT_EQ(payload_ptr[1], 188); // 188 = 0b10111100
    ASSERT_EQ(payload_ptr[2], 2);   // 2 = 0b00000010
}

TEST_F(TestBaseCommands, testGetPLDMCommandsBadRequest)
{
    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_REQ_BYTES>
        requestPayload{};
    auto request = new (requestPayload.data()) pldm_msg;

    request->payload[0] = 0xFF;
    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
    base::Handler handler(event);
    auto response = handler.getPLDMCommands(request, requestPayloadLength);
    auto responsePtr = new (response.data()) pldm_msg;
    uint8_t* payload_ptr = responsePtr->payload;
    ASSERT_EQ(payload_ptr[0], PLDM_ERROR_INVALID_PLDM_TYPE);
}

TEST_F(TestBaseCommands, testGetPLDMVersionGoodRequest)
{
    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES>
        requestPayload{};
    auto request = new (requestPayload.data()) pldm_msg;
    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);

    uint8_t pldmType = PLDM_BASE;
    uint32_t transferHandle = 0x0;
    uint8_t flag = PLDM_GET_FIRSTPART;
    uint8_t retFlag = PLDM_START_AND_END;
    ver32_t version = {0x00, 0xF0, 0xF0, 0xF1};

    auto rc =
        encode_get_version_req(0, transferHandle, flag, pldmType, request);

    ASSERT_EQ(0, rc);

    base::Handler handler(event);
    auto response = handler.getPLDMVersion(request, requestPayloadLength);
    auto responsePtr = new (response.data()) pldm_msg;

    ASSERT_EQ(responsePtr->payload[0], 0);
    ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]),
                        &transferHandle, sizeof(transferHandle)));
    ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]) +
                            sizeof(transferHandle),
                        &retFlag, sizeof(flag)));
    ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]) +
                            sizeof(transferHandle) + sizeof(flag),
                        &version, sizeof(version)));

    uint32_t expectedChecksum = pldm_edac_crc32(&version, sizeof(version));
    uint32_t responseChecksum = 0;
    memcpy(&responseChecksum,
           responsePtr->payload + PLDM_GET_VERSION_RESP_BYTES,
           sizeof(responseChecksum));
    ASSERT_EQ(expectedChecksum, le32toh(responseChecksum));
}

TEST_F(TestBaseCommands, testGetPLDMVersionBadRequest)
{
    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES>
        requestPayload{};
    auto request = new (requestPayload.data()) pldm_msg;
    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);

    uint8_t pldmType = 6;
    uint32_t transferHandle = 0x0;
    uint8_t flag = PLDM_GET_FIRSTPART;

    auto rc =
        encode_get_version_req(0, transferHandle, flag, pldmType, request);

    ASSERT_EQ(0, rc);

    base::Handler handler(event);
    auto response = handler.getPLDMVersion(request, requestPayloadLength - 1);
    auto responsePtr = new (response.data()) pldm_msg;

    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);

    request = new (requestPayload.data()) pldm_msg;
    requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);

    rc = encode_get_version_req(0, transferHandle, flag, pldmType, request);

    ASSERT_EQ(0, rc);

    response = handler.getPLDMVersion(request, requestPayloadLength);
    responsePtr = new (response.data()) pldm_msg;

    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_PLDM_TYPE);
}

TEST_F(TestBaseCommands, testGetTIDGoodRequest)
{
    std::array<uint8_t, sizeof(pldm_msg_hdr)> requestPayload{};
    auto request = new (requestPayload.data()) pldm_msg;
    size_t requestPayloadLength = 0;

    base::Handler handler(event);
    handler.setOemPlatformHandler(nullptr);
    auto response = handler.getTID(request, requestPayloadLength);

    auto responsePtr = new (response.data()) pldm_msg;
    uint8_t* payload = responsePtr->payload;

    ASSERT_EQ(payload[0], 0);
    ASSERT_EQ(payload[1], 1);
}

TEST_F(TestBaseCommands, testSetMultiPartSizeCallback)
{
    base::Handler handler(event);

    // Prepare a NegotiateTransferParameters request
    std::vector<uint8_t> requestMsg(
        sizeof(pldm_msg_hdr) +
        PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES);
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);

    struct pldm_base_negotiate_transfer_params_req req{};
    req.requester_part_size = 1024;
    // PLDM_FILE is type 7. index = 7/8 = 0. bit = 7%8 = 7.
    req.requester_protocol_support[0].byte |= (1 << 7);

    EXPECT_EQ(encode_pldm_base_negotiate_transfer_params_req(
                  /*instance_id=*/1, &req, request, &requestPayloadLength),
              0);

    // Call getNegotiateTransferParam to trigger the callback
    requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
    auto response =
        handler.getNegotiateTransferParam(1, request, requestPayloadLength);

    // Verify the response
    ASSERT_FALSE(response.empty());
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());

    struct pldm_base_negotiate_transfer_params_resp resp;
    EXPECT_EQ(decode_pldm_base_negotiate_transfer_params_resp(
                  responsePtr, response.size() - sizeof(pldm_msg_hdr), &resp),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);
    EXPECT_EQ(resp.responder_part_size, PLDM_RESPONDER_PART_SIZE);
    EXPECT_TRUE(resp.responder_protocol_support[0].byte & (1 << 7));
}

TEST_F(TestBaseCommands, testNegotiateTransferParamMultipleTIDs)
{
    base::Handler handler(event);

    // Map of TIDs to their requested part sizes
    std::map<pldm_tid_t, uint16_t> tidToPartSize = {
        {10, 512},   // smaller than responder
        {20, 8192},  // larger than responder
        {30, 4096},  // equal to responder
        {40, 1024}}; // smaller than responder

    for (const auto& [tid, requester_part_size] : tidToPartSize)
    {
        // Prepare a NegotiateTransferParameters request
        std::vector<uint8_t> requestMsg(
            sizeof(pldm_msg_hdr) +
            PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES);
        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
        size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);

        // Fill in the request payload
        struct pldm_base_negotiate_transfer_params_req req{};
        req.requester_part_size = requester_part_size;
        // PLDM_FILE is type 7. index = 7/8 = 0. bit = 7%8 = 7.
        req.requester_protocol_support[0].byte |= (1 << 7);

        EXPECT_EQ(encode_pldm_base_negotiate_transfer_params_req(
                      /*instance_id=*/1, &req, request, &requestPayloadLength),
                  0);

        // Call getNegotiateTransferParam
        auto response = handler.getNegotiateTransferParam(tid, request,
                                                          requestPayloadLength);

        // Verify the response
        ASSERT_FALSE(response.empty()) << "Failed for TID " << (int)tid;
        auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());

        struct pldm_base_negotiate_transfer_params_resp resp;
        EXPECT_EQ(decode_pldm_base_negotiate_transfer_params_resp(
                      responsePtr, response.size() - sizeof(pldm_msg_hdr),
                      &resp),
                  0);

        EXPECT_EQ(resp.completion_code, PLDM_SUCCESS)
            << "Failed for TID " << (int)tid;

        // Verify the negotiated part size for this TID
        uint16_t expectedNegotiatedSize =
            std::min(requester_part_size, (uint16_t)PLDM_RESPONDER_PART_SIZE);
        uint16_t negotiatedSize = handler.getNegotiatedPartSize(tid, PLDM_FILE);
        EXPECT_EQ(negotiatedSize, expectedNegotiatedSize)
            << "Failed for TID " << (int)tid;
    }
}

TEST_F(TestBaseCommands, testNegotiateTransferParamInvalidLength)
{
    std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 1);
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t payloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);

    base::Handler handler(event);
    auto response =
        handler.getNegotiateTransferParam(1, request, payloadLength);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());

    struct pldm_base_negotiate_transfer_params_resp resp;
    EXPECT_EQ(decode_pldm_base_negotiate_transfer_params_resp(
                  responsePtr, response.size() - sizeof(pldm_msg_hdr), &resp),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_ERROR);
}

TEST_F(TestBaseCommands, testNegotiateTransferParamInvalidPartSizeZero)
{
    std::vector<uint8_t> requestMsg(
        sizeof(pldm_msg_hdr) +
        PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES);
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t payloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);

    struct pldm_base_negotiate_transfer_params_req req{};
    req.requester_part_size = 0;
    EXPECT_EQ(encode_pldm_base_negotiate_transfer_params_req(1, &req, request,
                                                             &payloadLength),
              0);

    base::Handler handler(event);
    auto response =
        handler.getNegotiateTransferParam(1, request, payloadLength);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());

    struct pldm_base_negotiate_transfer_params_resp resp;
    EXPECT_EQ(decode_pldm_base_negotiate_transfer_params_resp(
                  responsePtr, response.size() - sizeof(pldm_msg_hdr), &resp),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_ERROR_INVALID_DATA);
}

TEST_F(TestBaseCommands, testNegotiateTransferParamInvalidPartSizeNotPowerOfTwo)
{
    std::vector<uint8_t> requestMsg(
        sizeof(pldm_msg_hdr) +
        PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES);
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t payloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);

    struct pldm_base_negotiate_transfer_params_req req{};
    req.requester_part_size = 3000;
    EXPECT_EQ(encode_pldm_base_negotiate_transfer_params_req(1, &req, request,
                                                             &payloadLength),
              0);

    base::Handler handler(event);
    auto response =
        handler.getNegotiateTransferParam(1, request, payloadLength);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    struct pldm_base_negotiate_transfer_params_resp resp;
    EXPECT_EQ(decode_pldm_base_negotiate_transfer_params_resp(
                  responsePtr, response.size() - sizeof(pldm_msg_hdr), &resp),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_ERROR_INVALID_DATA);
}

TEST_F(TestBaseCommands, testNegotiateTransferParamGoodRequest)
{
    std::vector<uint8_t> requestMsg(
        sizeof(pldm_msg_hdr) +
        PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES);
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t payloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);

    struct pldm_base_negotiate_transfer_params_req req{};
    req.requester_part_size = 4096;
    EXPECT_EQ(encode_pldm_base_negotiate_transfer_params_req(1, &req, request,
                                                             &payloadLength),
              0);

    base::Handler handler(event);
    auto response =
        handler.getNegotiateTransferParam(1, request, payloadLength);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());

    struct pldm_base_negotiate_transfer_params_resp resp;
    EXPECT_EQ(decode_pldm_base_negotiate_transfer_params_resp(
                  responsePtr, response.size() - sizeof(pldm_msg_hdr), &resp),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);
    EXPECT_EQ(resp.responder_part_size, PLDM_RESPONDER_PART_SIZE);
}
