// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "google3/host_commands.h"

#include "host_command_mock.hpp"
#include "payload_update.hpp"
#include "payload_update_interface.hpp"
#include "sys_mock.hpp"
#include "test/payload_update_mock.hpp"

#include <fcntl.h>

#include <stdplus/raw.hpp>
#include <xyz/openbmc_project/Control/Hoth/error.hpp>

#include <cstdint>
#include <random>
#include <span>
#include <string>
#include <vector>

#include "gmock/gmock.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>

using namespace std::literals;
using sdbusplus::error::xyz::openbmc_project::control::hoth::CommandFailure;
using sdbusplus::error::xyz::openbmc_project::control::hoth::ResponseFailure;

using ::testing::_;
using ::testing::ContainerEq;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::Throw;

namespace google
{
namespace hoth
{
namespace internal
{
namespace
{

auto const goodResponseStr = "\x03\xfd\x00\x00\x00\x00\x00\x00"s;
std::vector<uint8_t> const gooodResponse(goodResponseStr.begin(),
                                         goodResponseStr.end());

class PayloadUpdateTest : public ::testing::Test
{
  protected:
    PayloadUpdateTest() : payloadUpdate(&hostCmd, &sys)
    {}
    // Sys mock
    const internal::SysMock sys;

    // Host Command interface handle
    internal::HostCommandMock hostCmd;

    // PayloadUpdate interface handle
    internal::PayloadUpdateImpl payloadUpdate;
};

MATCHER_P(requestMatches, req, "")
{
    const auto* const arg_req = static_cast<const payload_update_packet *>(arg);
    return (arg_req->offset == req.offset && arg_req->len == req.len &&
            arg_req->type == req.type);
}

class PayloadInitiateTest : public PayloadUpdateTest
{
  protected:
    // Expected request {offset, len, type}
    const payload_update_packet expectedReq = {0, 0, PAYLOAD_UPDATE_INITIATE};
};

TEST_F(PayloadInitiateTest, sendCommandExceptionFails)
{
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Throw(CommandFailure()));

    EXPECT_THROW(payloadUpdate.initiate(), CommandFailure);
}

TEST_F(PayloadInitiateTest, sendCommandReturnsEmptyResultFails)
{
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(std::vector<uint8_t>{}));

    EXPECT_THROW(payloadUpdate.initiate(), std::runtime_error);
}

TEST_F(PayloadInitiateTest, sendCommandReturnsBadResultFails)
{
    std::vector<uint8_t> rsp = gooodResponse;
    // Change the RspHeader.result to something other than EC_RES_SUCCESS
    rsp[2] = internal::EC_RES_ERROR;

    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(rsp));

    EXPECT_THROW(payloadUpdate.initiate(), ResponseFailure);
}

TEST_F(PayloadInitiateTest, sendCommandReturnsGoodResponseSuccess)
{
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(gooodResponse));

    EXPECT_NO_THROW(payloadUpdate.initiate());
}

class PayloadEraseTest : public PayloadUpdateTest
{
  protected:
    const uint32_t expectedOffset = 0;
    const uint32_t expectedSize = 4096;
    // Expected request {offset, len, type}
    const payload_update_packet expectedReq = {expectedOffset, expectedSize,
                                               PAYLOAD_UPDATE_ERASE};
};

TEST_F(PayloadEraseTest, sendCommandExceptionFails)
{
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Throw(CommandFailure()));

    EXPECT_THROW(payloadUpdate.erase(expectedOffset, expectedSize),
                 CommandFailure);
}

TEST_F(PayloadEraseTest, sendCommandReturnsBadResultFails)
{
    std::vector<uint8_t> rsp = gooodResponse;
    // Change the RspHeader.result to something other than EC_RES_SUCCESS
    rsp[2] = internal::EC_RES_ERROR;

    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(rsp));

    EXPECT_THROW(payloadUpdate.erase(expectedOffset, expectedSize),
                 ResponseFailure);
}

TEST_F(PayloadEraseTest, sendCommandReturnsEmptyResultFails)
{
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(std::vector<uint8_t>{}));

    EXPECT_THROW(payloadUpdate.erase(expectedOffset, expectedSize),
                 std::runtime_error);
}

TEST_F(PayloadEraseTest, sendCommandReturnsGoodResponseSuccess)
{
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(gooodResponse));

    EXPECT_NO_THROW(payloadUpdate.erase(expectedOffset, expectedSize));
}

class PayloadReadTest : public PayloadUpdateTest
{
  protected:
    static constexpr uint32_t expectedOffset = 10;
    static constexpr uint32_t expectedSize = 3;
    // Expected request {offset, len, type}
    const payload_update_packet expectedReq = {expectedOffset, expectedSize,
                                               PAYLOAD_UPDATE_READ};

    static std::vector<uint8_t> makeResponse(std::span<const uint8_t> data)
    {
        internal::RspHeader hdr;
        auto hdrSpan = stdplus::raw::asSpan<uint8_t>(hdr);
        hdr.struct_version = 3;
        hdr.checksum = 0;
        hdr.result = 0;
        hdr.data_len = data.size();
        hdr.reserved = 0;
        hdr.checksum += -internal::calculateChecksum(hdrSpan, data);

        std::vector<uint8_t> ret;
        ret.insert(ret.end(), hdrSpan.begin(), hdrSpan.end());
        ret.insert(ret.end(), data.begin(), data.end());
        return ret;
    }
};

TEST_F(PayloadReadTest, sendCommandReturnsShortResultFails)
{
    constexpr std::array<uint8_t, expectedSize - 1> shortRsp = {1, 3};
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(makeResponse(shortRsp)));

    std::array<uint8_t, expectedSize> rsp;
    EXPECT_THROW(payloadUpdate.read(expectedOffset, rsp), ResponseFailure);
}

TEST_F(PayloadReadTest, sendCommandReturnsGoodResponseSuccess)
{
    constexpr std::array<uint8_t, expectedSize> expectedRsp = {4, 5, 6};
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(makeResponse(expectedRsp)));

    std::array<uint8_t, expectedSize> rsp;
    payloadUpdate.read(expectedOffset, rsp);
    EXPECT_EQ(expectedRsp, rsp);
}

std::vector<uint8_t> makeRsp(uint16_t result)
{
    std::vector<uint8_t> ret(sizeof(RspHeader));
    auto& rsp = stdplus::raw::refFrom<RspHeader>(ret);
    rsp.result = result;
    return ret;
}

class PayloadVerifyTest : public PayloadUpdateTest
{
  protected:
    // Expected request {offset, len, type}
    const payload_update_packet expectedReq = {0, 0, PAYLOAD_UPDATE_VERIFY};
    const payload_update_packet expectedDescriptorReq = {
        0, 0, PAYLOAD_UPDATE_VERIFY_DESCRIPTOR};
};

TEST_F(PayloadVerifyTest, descriptorVerificationNotSupported)
{
    testing::InSequence seq;
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedDescriptorReq),
                                     sizeof(expectedDescriptorReq)))
        .WillOnce(Return(makeRsp(EC_RES_ERROR)));
    EXPECT_CALL(
        hostCmd,
        sendCommand(EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                    0, requestMatches(expectedReq), sizeof(expectedReq)))
        .WillOnce(Return(makeRsp(EC_RES_SUCCESS)));

    // In case descriptor verfication is not successful, fall back to
    // PAYLOAD_UPDATE_VERIFY. Thus the two EXPECT_CALLs above.
    EXPECT_NO_THROW(payloadUpdate.verify());
}

TEST_F(PayloadVerifyTest, descriptorVerificationSuccess)
{
    testing::InSequence seq;
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedDescriptorReq),
                                     sizeof(expectedDescriptorReq)))
        .WillOnce(Return(makeRsp(EC_RES_SUCCESS)));

    EXPECT_NO_THROW(payloadUpdate.verify());
}

TEST_F(PayloadVerifyTest, sendCommandExceptionFails)
{
    testing::InSequence seq;
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedDescriptorReq),
                                     sizeof(expectedDescriptorReq)))
        .WillOnce(Return(makeRsp(EC_RES_INVALID_PARAM)));
    EXPECT_CALL(
        hostCmd,
        sendCommand(EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                    0, requestMatches(expectedReq), sizeof(expectedReq)))
        .WillOnce(Throw(CommandFailure()));

    EXPECT_THROW(payloadUpdate.verify(), CommandFailure);
}

TEST_F(PayloadVerifyTest, sendCommandReturnsBadResultFails)
{
    testing::InSequence seq;
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedDescriptorReq),
                                     sizeof(expectedDescriptorReq)))
        .WillOnce(Return(makeRsp(EC_RES_INVALID_PARAM)));
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(makeRsp(EC_RES_ERROR)));

    EXPECT_THROW(payloadUpdate.verify(), ResponseFailure);
}

TEST_F(PayloadVerifyTest, sendCommandReturnsEmptyResultFails)
{
    testing::InSequence seq;
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedDescriptorReq),
                                     sizeof(expectedDescriptorReq)))
        .WillOnce(Return(makeRsp(EC_RES_INVALID_PARAM)));
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(std::vector<uint8_t>{}));

    EXPECT_THROW(payloadUpdate.verify(), std::runtime_error);
}

TEST_F(PayloadVerifyTest, sendCommandReturnsGoodResponseSuccess)
{
    testing::InSequence seq;
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedDescriptorReq),
                                     sizeof(expectedDescriptorReq)))
        .WillOnce(Return(makeRsp(EC_RES_INVALID_PARAM)));
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(gooodResponse));

    EXPECT_NO_THROW(payloadUpdate.verify());
}

class PayloadGetStatusTest : public PayloadUpdateTest
{
  protected:
    // Expected request {offset, len, type}
    const payload_update_packet expectedReq = {0, 0, PAYLOAD_UPDATE_GET_STATUS};
};

TEST_F(PayloadGetStatusTest, sendCommandExceptionFails)
{
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Throw(CommandFailure()));

    EXPECT_THROW(payloadUpdate.getStatus(), CommandFailure);
}

TEST_F(PayloadGetStatusTest, sendCommandReturnsBadResultFails)
{
    std::vector<uint8_t> rsp = gooodResponse;
    // Change the RspHeader.result to something other than EC_RES_SUCCESS
    rsp[2] = internal::EC_RES_ERROR;

    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(rsp));

    EXPECT_THROW(payloadUpdate.getStatus(), ResponseFailure);
}

TEST_F(PayloadGetStatusTest, sendCommandReturnsEmptyResultFails)
{
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(std::vector<uint8_t>{}));

    EXPECT_THROW(payloadUpdate.getStatus(), std::runtime_error);
}

TEST_F(PayloadGetStatusTest, sendCommandReturnsEmptyPayloadFails)
{
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(gooodResponse));

    EXPECT_THROW(payloadUpdate.getStatus(), std::runtime_error);
}

TEST_F(PayloadGetStatusTest, getStatusCheckValidResponseSuccess)
{
    payload_update_status expectedResponse;
    expectedResponse.a_valid = 1;
    expectedResponse.b_valid = 2;
    expectedResponse.active_half = 0;
    expectedResponse.next_half = 1;
    expectedResponse.persistent_half = 1;

    std::vector<uint8_t> rsp = gooodResponse;
    // Append expectedResponse to the response. Normally, checksum and data_len
    // would also need to be changed in the packet but since we're mocking out
    // sendCommand (which performs the check), we will just append.
    rsp.insert(rsp.end(), reinterpret_cast<uint8_t*>(&expectedResponse),
               reinterpret_cast<uint8_t*>(&expectedResponse) +
                   sizeof(expectedResponse));

    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, requestMatches(expectedReq),
                                     sizeof(payload_update_packet)))
        .WillOnce(Return(rsp));

    auto response = payloadUpdate.getStatus();

    EXPECT_EQ(response.a_valid, expectedResponse.a_valid);
    EXPECT_EQ(response.b_valid, expectedResponse.b_valid);
    EXPECT_EQ(response.active_half, expectedResponse.active_half);
    EXPECT_EQ(response.next_half, expectedResponse.next_half);
    EXPECT_EQ(response.persistent_half, expectedResponse.persistent_half);
}

MATCHER_P(activateRequestMatches, req, "")
{

  const auto*const arg_req = static_cast<const internal::ActivateRequest*>(arg);
  return (arg_req->header.offset == req.header.offset &&
          arg_req->header.len == req.header.len &&
          arg_req->header.type == req.header.type &&
          arg_req->activate.half == req.activate.half &&
          arg_req->activate.make_persistent == req.activate.make_persistent);
}

class PayloadActivateTest : public PayloadUpdateTest
{
  protected:
    // Expected request header {offset, len, type}
    const payload_update_packet expectedHeader = {
        0, sizeof(payload_update_activate), PAYLOAD_UPDATE_ACTIVATE};
    const internal::Side expectedSide = internal::Side::A;
    const internal::Persistence expectedPersistence =
        internal::Persistence::kNonPersistent;
    const payload_update_activate expectedActivate = {
        static_cast<uint8_t>(expectedSide),
        static_cast<uint8_t>(expectedPersistence)};
    const internal::ActivateRequest expectedReq = {expectedHeader,
                                                   expectedActivate};

    payload_update_status response;
};

TEST_F(PayloadActivateTest, sendCommandExceptionFails)
{
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, activateRequestMatches(expectedReq),
                                     sizeof(internal::ActivateRequest)))
        .WillOnce(Throw(CommandFailure()));

    EXPECT_THROW(payloadUpdate.activate(expectedSide, expectedPersistence),
                 CommandFailure);
}

TEST_F(PayloadActivateTest, sendCommandReturnsBadResultFails)
{
    std::vector<uint8_t> rsp = gooodResponse;
    // Change the RspHeader.result to something other than EC_RES_SUCCESS
    rsp[2] = internal::EC_RES_ERROR;

    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, activateRequestMatches(expectedReq),
                                     sizeof(internal::ActivateRequest)))
        .WillOnce(Return(rsp));

    EXPECT_THROW(payloadUpdate.activate(expectedSide, expectedPersistence),
                 ResponseFailure);
}

TEST_F(PayloadActivateTest, sendCommandReturnsEmptyResultFails)
{
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, activateRequestMatches(expectedReq),
                                     sizeof(internal::ActivateRequest)))
        .WillOnce(Return(std::vector<uint8_t>{}));

    EXPECT_THROW(payloadUpdate.activate(expectedSide, expectedPersistence),
                 std::runtime_error);
}

TEST_F(PayloadActivateTest, sendCommandReturnsGoodResponseSuccess)
{
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, activateRequestMatches(expectedReq),
                                     sizeof(internal::ActivateRequest)))
        .WillOnce(Return(gooodResponse));

    EXPECT_NO_THROW(payloadUpdate.activate(expectedSide, expectedPersistence));
}

class PayloadConfirmTest : public PayloadUpdateTest
{

  protected:
    // Expected request header {offset, len, type}
    const payload_update_packet expectedHeader = {
        0, sizeof(payload_update_confirm), PAYLOAD_UPDATE_CONFIRM};

    // Expected confirm
    enum payload_update_confirm_option option =
        payload_update_confirm_option::Confirm;
    uint32_t timeoute_value = 3600;
    uint64_t cookie = 0;
    const payload_update_confirm expectedConfirm = {
        option, {0, 0, 0}, 3600, cookie};
    const internal::ConfirmRequest expectedReq = {expectedHeader,
                                                  expectedConfirm};

    std::optional<payload_update_confirm_response> response;
};

MATCHER_P(confirmRequestMatches, req, "")
{

    const auto *const arg_req =
        static_cast<const internal::ConfirmRequest *>(arg);
    return (arg_req->header.offset == req.header.offset &&
            arg_req->header.len == req.header.len &&
            arg_req->header.type == req.header.type &&
            arg_req->confirm.option == req.confirm.option &&
            arg_req->confirm.timeout_value == req.confirm.timeout_value &&
            arg_req->confirm.confirmation_cookie ==
                req.confirm.confirmation_cookie);
}

TEST_F(PayloadConfirmTest, sendCommandReturnsGoodResponseSuccess)
{
    // every things is good, and the command works
    payload_update_confirm_response expectedResponse;
    expectedResponse.timeout_values.min = 1;
    expectedResponse.timeout_values.max = 2;
    expectedResponse.timeout_values.default_val = 3;
    expectedResponse.timeout_values.current = 4;

    std::vector<uint8_t> rsp = gooodResponse;
    rsp.insert(rsp.end(), reinterpret_cast<uint8_t*>(&expectedResponse),
               reinterpret_cast<uint8_t*>(&expectedResponse) +
                   sizeof(expectedResponse));

    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, confirmRequestMatches(expectedReq),
                                     sizeof(internal::ConfirmRequest)))
        .WillOnce(Return(rsp));
    std::optional<payload_update_confirm_response> response;

    EXPECT_NO_THROW(response = payloadUpdate.confirm(
                        payload_update_confirm_option::Confirm, 3600, 0));
    EXPECT_NE(response, std::nullopt);
    EXPECT_EQ(response->timeout_values.min,
              expectedResponse.timeout_values.min);
    EXPECT_EQ(response->timeout_values.max,
              expectedResponse.timeout_values.max);
    EXPECT_EQ(response->timeout_values.default_val,
              expectedResponse.timeout_values.default_val);
    EXPECT_EQ(response->timeout_values.current,
              expectedResponse.timeout_values.current);
}

TEST_F(PayloadConfirmTest, sendCommandReturnsBadResultFails)
{
    // the good call, but the fucntion will return a bad response
    // this should cause a ResponseFailure
    std::vector<uint8_t> rsp = gooodResponse;
    rsp[2] = internal::EC_RES_ERROR;

    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, confirmRequestMatches(expectedReq),
                                     sizeof(internal::ConfirmRequest)))
        .WillOnce(Return(rsp));

    std::optional<payload_update_confirm_response> response;
    EXPECT_THROW(response = payloadUpdate.confirm(
                     payload_update_confirm_option::Confirm, 3600, 0),
                 ResponseFailure);
}

TEST_F(PayloadConfirmTest, sendCommandReturnsEmptyResultFails)
{
    // the call is good, but out expected call (sendCmd) return a empty vector
    // this should cause a runtime error
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, confirmRequestMatches(expectedReq),
                                     sizeof(internal::ConfirmRequest)))
        .WillOnce(Return(std::vector<uint8_t>{}));

    std::optional<payload_update_confirm_response> response;
    EXPECT_THROW(response = payloadUpdate.confirm(
                     payload_update_confirm_option::Confirm, 3600, 0),
                 std::runtime_error);
}

TEST_F(PayloadConfirmTest, sendCommandExceptionFails)
{
    // the call is good, but out expected call creates a "commandFailure"
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     0, confirmRequestMatches(expectedReq),
                                     sizeof(internal::ConfirmRequest)))
        .WillOnce(Throw(CommandFailure()));

    std::optional<payload_update_confirm_response> response;
    EXPECT_THROW(response = payloadUpdate.confirm(
                     payload_update_confirm_option::Confirm, 3600, 0),
                 CommandFailure);
}

class PayloadSendTest : public PayloadUpdateTest
{
  protected:
    const std::string expectedPath = "/run/initramfs/bmc-image";
    const int expectedFd = 1;
    const int expectedRetClose = 0;
    const ssize_t endRead = 0;
};

TEST_F(PayloadSendTest, sysOpenReturnNegativeFails)
{
    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY)).WillOnce(Return(-1));
    // We do not expect sys close to be called since open failed
    EXPECT_CALL(sys, close(_)).Times(0);

    EXPECT_THROW(payloadUpdate.send(expectedPath), std::system_error);
}

TEST_F(PayloadSendTest, sysReadReturnNegativeFails)
{
    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY))
        .WillOnce(Return(expectedFd));
    EXPECT_CALL(sys, read(expectedFd, _, internal::max_packet_size))
        .WillOnce(Return(-1));
    EXPECT_CALL(sys, close(expectedFd)).Times(1);

    EXPECT_THROW(payloadUpdate.send(expectedPath), std::system_error);
}

TEST_F(PayloadSendTest, sysReadThrowsErrorFails)
{
    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY))
        .WillOnce(Return(expectedFd));
    EXPECT_CALL(sys, read(expectedFd, _, internal::max_packet_size))
        .WillOnce(Throw(internal::errnoException("")));
    EXPECT_CALL(sys, close(expectedFd)).Times(1);

    EXPECT_THROW(payloadUpdate.send(expectedPath), std::system_error);
}

TEST_F(PayloadSendTest, hostCmdSendCommandThrowsErrorFails)
{
    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY))
        .WillOnce(Return(expectedFd));
    EXPECT_CALL(sys, read(expectedFd, _, internal::max_packet_size))
        .WillOnce([](int, void* data, size_t size) {
            memset(data, 0, size);
            return size;
        });
    EXPECT_CALL(hostCmd, sendCommand(_, _, _, _))
        .WillOnce(Throw(ResponseFailure()));
    EXPECT_CALL(sys, close(expectedFd)).Times(1);

    EXPECT_THROW(payloadUpdate.send(expectedPath), ResponseFailure);
}

TEST_F(PayloadSendTest, sysCloseReturnPositiveSuccess)
{
    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY))
        .WillOnce(Return(expectedFd));
    // Return 0 to emulate read finishing a read of file 0
    EXPECT_CALL(sys, read(expectedFd, _, internal::max_packet_size))
        .WillOnce(Return(endRead));
    EXPECT_CALL(sys, close(expectedFd)).WillOnce(Return(expectedRetClose));

    EXPECT_NO_THROW(payloadUpdate.send(expectedPath));
}

class PayloadFindDescriptorTest : public PayloadUpdateTest
{
  protected:
    const std::string expectedPath = "/run/initramfs/bmc-image";
    const int expectedFd = 1;
    const int expectedRetClose = 0;
    const ssize_t endRead = 0;
    const int fsize = 32 * 1024;
    uint32_t offset = 0;
};

TEST_F(PayloadFindDescriptorTest, sysOpenReturnNegativeFails)
{
    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY)).WillOnce(Return(-1));
    // We do not expect sys close to be called since open failed
    EXPECT_CALL(sys, close(_)).Times(0);

    EXPECT_THROW(payloadUpdate.findDescriptor(expectedPath, &offset),
                 std::system_error);
}

TEST_F(PayloadFindDescriptorTest, sysSeekReturnNegativeFails)
{
    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY))
        .WillOnce(Return(expectedFd));
    EXPECT_CALL(sys, lseek(expectedFd, _, _)).WillOnce(Return(-1));
    EXPECT_CALL(sys, close(_)).Times(1);

    EXPECT_THROW(payloadUpdate.findDescriptor(expectedPath, &offset),
                 std::system_error);
}

TEST_F(PayloadFindDescriptorTest, sysReadReturnNegativeFails)
{
    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY))
        .WillOnce(Return(expectedFd));
    EXPECT_CALL(sys, lseek(expectedFd, _, _)).WillRepeatedly(Return(fsize));
    EXPECT_CALL(sys, read(expectedFd, _, _)).WillOnce(Return(-1));
    EXPECT_CALL(sys, close(_)).Times(1);

    EXPECT_THROW(payloadUpdate.findDescriptor(expectedPath, &offset),
                 std::system_error);
}

TEST_F(PayloadFindDescriptorTest, sysCloseReturnPositiveSuccess)
{
    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY))
        .WillOnce(Return(expectedFd));
    EXPECT_CALL(sys, lseek(expectedFd, _, _)).WillRepeatedly(Return(fsize));

    // Return 0 to emulate read finishing a read of file 0
    EXPECT_CALL(sys, read(expectedFd, _, _)).WillRepeatedly(Return(endRead));
    EXPECT_CALL(sys, close(expectedFd)).WillOnce(Return(expectedRetClose));

    EXPECT_NO_THROW(payloadUpdate.findDescriptor(expectedPath, &offset));
}

class PayloadSendStaticWPTest : public PayloadUpdateTest
{
  protected:
    const std::string expectedPath = "/run/initramfs/bmc-image";
    const int expectedFd = 1;
    const int expectedRetClose = 0;
    const int fsize = 32 * 1024;
};

TEST_F(PayloadSendStaticWPTest, findDescriptorReturnNegativeFails)
{

    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY))
        .WillOnce(Return(expectedFd));
    EXPECT_CALL(sys, lseek(expectedFd, _, _)).WillRepeatedly(Return(fsize));

    EXPECT_CALL(sys, close(_)).Times(1);

    EXPECT_THROW(payloadUpdate.eraseAndSendStaticWP(expectedPath),
                 std::system_error);
} // namespace internal

class PayloadSendStaticWPRegionsTest : public PayloadUpdateTest
{
  protected:
    const std::string expectedPath = "/run/initramfs/bmc-image";
    const int expectedFd = 1;
    const int expectedRetClose = 0;
    const ssize_t endRead = 0;
    const int fsize = 32 * 1024;
    uint32_t offset = 0;
};

TEST_F(PayloadSendStaticWPRegionsTest, sysOpenReturnNegativeFails)
{
    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY)).WillOnce(Return(-1));
    // We do not expect sys close to be called since open failed
    EXPECT_CALL(sys, close(_)).Times(0);

    EXPECT_THROW(
        payloadUpdate.eraseAndSendStaticWPRegions(expectedPath, offset),
        std::system_error);
}

TEST_F(PayloadSendStaticWPRegionsTest, sysSeekReturnNegativeFails)
{
    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY))
        .WillOnce(Return(expectedFd));
    EXPECT_CALL(sys, lseek(expectedFd, _, _)).WillOnce(Return(-1));
    EXPECT_CALL(sys, close(_)).Times(1);

    EXPECT_THROW(
        payloadUpdate.eraseAndSendStaticWPRegions(expectedPath, offset),
        std::system_error);
}

TEST_F(PayloadSendStaticWPRegionsTest, sysReadReturnNegativeFails)
{
    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY))
        .WillOnce(Return(expectedFd));
    EXPECT_CALL(sys, lseek(expectedFd, _, _)).WillRepeatedly(Return(fsize));
    EXPECT_CALL(sys, read(expectedFd, _, _)).WillOnce(Return(-1));
    EXPECT_CALL(sys, close(_)).Times(1);
    EXPECT_THROW(
        payloadUpdate.eraseAndSendStaticWPRegions(expectedPath, offset),
        std::system_error);
} // namespace internal

TEST_F(PayloadSendStaticWPRegionsTest, invalidDescriptorFails)
{
    EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY))
        .WillOnce(Return(expectedFd));
    EXPECT_CALL(sys, lseek(expectedFd, _, _)).WillRepeatedly(Return(fsize));
    EXPECT_CALL(sys, read(expectedFd, _, _)).WillOnce(Return(fsize));
    EXPECT_THROW(
        payloadUpdate.eraseAndSendStaticWPRegions(expectedPath, offset),
        std::system_error);
} // namespace internal

constexpr uint32_t testFlashSize = 32 * 1024;
class PayloadChunkAndSendTest : public PayloadSendTest
{
    // Needs to be public in order to be used in TEST_P
  public:
    PayloadChunkAndSendTest()
    {
        EXPECT_CALL(sys, open(expectedPath.c_str(), O_RDONLY))
            .WillOnce(Return(expectedFd));
        // Due to the RAII handler, we always expect close to be called if open
        // succeeded
        EXPECT_CALL(sys, close(expectedFd)).WillOnce(Return(expectedRetClose));
    }
};

class FakeFile
{
  public:
    // Generate all 0xff file
    explicit FakeFile(uint32_t size) : file(size, 0xff) {}
    // Generate all 0xff file with random data between the 2 params passed in
    FakeFile(uint32_t randStartOffset, uint32_t randEndOffset, uint32_t size) :
        file(size, 0xff)
    {
        std::mt19937 gen(0);
        if (randEndOffset > size)
        {
            throw std::runtime_error(
                "RandEndOffset cannot be bigger than size of file");
        }

        auto fileIt = file.begin();
        std::generate(fileIt + randStartOffset, fileIt + randEndOffset, gen);
    }
    // Copy the file passed in manually
    explicit FakeFile(const std::vector<uint8_t> &file)
    {
        this->file = file;
    }

    ssize_t read(int /*unused*/, void *buf, size_t size)
    {
        auto readSize = std::min(static_cast<off_t>(file.size()) - readOffset,
                                static_cast<off_t>(size));

        if (readSize < 0)
        {
            return 0;
        }

        std::memcpy(buf, file.data() + readOffset, readSize);
        readOffset += readSize;
        return readSize;
    }

    std::vector<uint8_t> file;
    off_t readOffset = 0;
};

class FakeFlash
{
  public:
    explicit FakeFlash(uint32_t size) : flash(size, 0xff) {}

    std::vector<uint8_t> sendCommand(uint16_t /*unused*/, uint8_t /*unused*/,
                                     const void *request, size_t requestSize)
    {
        std::span<const uint8_t> reqSpan(
            reinterpret_cast<const uint8_t *>(request), requestSize);
        auto reqHeader = stdplus::raw::extract<payload_update_packet>(reqSpan);
        EXPECT_EQ(reqHeader.type, PAYLOAD_UPDATE_CONTINUE);

        std::memcpy(flash.data() + reqHeader.offset, reqSpan.data(),
                    reqHeader.len);
        // We need to ensure "result" member is EC_RES_SUCCESS so that
        // PayloadUpdateImpl::sendCommand does not throw
        return gooodResponse;
    }

    std::vector<uint8_t> flash;
};

TEST_F(PayloadChunkAndSendTest, chunkAndSendAllFFsSuccess)
{
    FakeFile file(testFlashSize);
    FakeFlash flash(testFlashSize);

    EXPECT_CALL(sys, read(expectedFd, _, internal::max_packet_size))
        .WillRepeatedly(Invoke(&file, &FakeFile::read));
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     _, _, _))
        .WillRepeatedly(Invoke(&flash, &FakeFlash::sendCommand));

    EXPECT_NO_THROW(payloadUpdate.send(expectedPath));
    EXPECT_THAT(file.file, ContainerEq(flash.flash));
}

class PayloadChunkAndSendTestWithParam :
    public PayloadChunkAndSendTest,
    public testing::WithParamInterface<std::pair<uint32_t, uint32_t>>
{};

TEST_P(PayloadChunkAndSendTestWithParam, chunkAndSendPartialNonFFsSuccess)
{
    FakeFile file(GetParam().first, GetParam().second, testFlashSize);
    FakeFlash flash(testFlashSize);

    EXPECT_CALL(sys, read(expectedFd, _, internal::max_packet_size))
        .WillRepeatedly(Invoke(&file, &FakeFile::read));
    EXPECT_CALL(hostCmd, sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                         EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                     _, _, _))
        .WillRepeatedly(Invoke(&flash, &FakeFlash::sendCommand));

    EXPECT_NO_THROW(payloadUpdate.send(expectedPath));
    EXPECT_THAT(file.file, ContainerEq(flash.flash));
}

const std::vector<std::pair<uint32_t, uint32_t>> chunkAndSendTestParams{
    // Params: {randStartOffsets, randEndOffsets}
    // These determine the [first, last] range to randomize the payload file

    // All non-0xffs
    {0, testFlashSize},
    // First portion non-0xffs
    {0, testFlashSize / 2},
    {0, testFlashSize / 3},
    // Last portion non-0xffs
    {testFlashSize / 4, testFlashSize},
    {testFlashSize / 5, testFlashSize},
    // Middle portion non-0xffs
    {testFlashSize / 6, testFlashSize / 2},
    {testFlashSize / 7, testFlashSize / 3},
    {testFlashSize / 8, 7 * testFlashSize / 8},
    {testFlashSize / 9, 8 * testFlashSize / 9},
};

INSTANTIATE_TEST_CASE_P(WithFlags, PayloadChunkAndSendTestWithParam,
                        ::testing::ValuesIn(chunkAndSendTestParams));

} // namespace
} // namespace internal
} // namespace hoth
} // namespace google
