#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/utils.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
        auto payload =
            reinterpret_cast<pldm_base_negotiate_transfer_params_req*>(
                request->payload);
        payload->requester_part_size = htole16(requester_part_size);

        // Set the bit for PLDM_FILE_TRANSFER in requester_protocol_support
        memset(payload->requester_protocol_support, 0,
               sizeof(payload->requester_protocol_support));
        // PLDM_FILE is type 7. index = 7/8 = 0. bit = 7%8 = 7.
        payload->requester_protocol_support[0].byte |= (1 << 7);

        // 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);

    auto payload = reinterpret_cast<pldm_base_negotiate_transfer_params_req*>(
        request->payload);
    payload->requester_part_size = 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);

    auto payload = reinterpret_cast<pldm_base_negotiate_transfer_params_req*>(
        request->payload);
    payload->requester_part_size = 3000;

    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);

    auto payload = reinterpret_cast<pldm_base_negotiate_transfer_params_req*>(
        request->payload);
    payload->requester_part_size = htole16(4096);

    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);
}
