// 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 "hoth_update_unittest.hpp"

#include <cstdint>
#include <string_view>
#include <vector>

#include <gtest/gtest.h>

namespace ipmi_hoth
{

using ::testing::Return;

class HothUpdateWriteTest : public HothUpdateTest
{};

TEST_F(HothUpdateWriteTest, InvalidSessionWriteIsRejected)
{
    // Verify the hoth update handler checks for a valid session.

    std::vector<uint8_t> data = {0x1, 0x2};

    EXPECT_FALSE(hvn.write(session_, 0, data));
}

TEST_F(HothUpdateWriteTest, WritingTooMuchByOneByteFails)
{
    // Test the edge case of writing 1 byte too much with an offset of 0.
    // writing hvn.maxBufferSize + 1 at offset 0 is invalid.

    int bytes = hvn.maxBufferSize() + 1;
    std::vector<uint8_t> data(0x11);
    data.resize(bytes);
    ASSERT_EQ(bytes, data.size());

    EXPECT_CALL(dbus, pingHothd(std::string_view(""))).WillOnce(Return(true));

    EXPECT_TRUE(hvn.open(session_, hvn.requiredFlags(), legacyPath));

    EXPECT_FALSE(hvn.write(session_, 0, data));
}

TEST_F(HothUpdateWriteTest, WritingTooMuchByOffsetOfOne)
{
    // Test the edge case of writing hvn.maxBufferSize bytes (which is fine)
    // but at the offset 1, which makes it go over by 1 byte.
    // writing hvn.maxBufferSize + offset 1 is invalid.

    int bytes = hvn.maxBufferSize();
    std::vector<uint8_t> data(0x11);
    data.resize(bytes);
    ASSERT_EQ(bytes, data.size());

    EXPECT_CALL(dbus, pingHothd(std::string_view(""))).WillOnce(Return(true));

    EXPECT_TRUE(hvn.open(session_, hvn.requiredFlags(), legacyPath));

    // offset of 1.
    EXPECT_FALSE(hvn.write(session_, 1, data));
}

TEST_F(HothUpdateWriteTest, WritingOneByteBeyondEndFromOffsetFails)
{
    // Test the edge case of writing to the last byte offset but trying to
    // write two bytes.
    // writing 2 bytes at hvn.maxBufferSize - 1 is invalid.

    std::vector<uint8_t> data = {0x01, 0x02};
    ASSERT_EQ(2, data.size());

    EXPECT_CALL(dbus, pingHothd(std::string_view(""))).WillOnce(Return(true));

    EXPECT_TRUE(hvn.open(session_, hvn.requiredFlags(), legacyPath));

    EXPECT_FALSE(hvn.write(session_, (hvn.maxBufferSize() - 1), data));
}

TEST_F(HothUpdateWriteTest, WritingOneByteAtOffsetBeyondEndFails)
{
    // Test the edge case of writing one byte but exactly one byte beyond the
    // buffer.
    // writing 1 byte at hvn.maxBufferSize is invalid.

    std::vector<uint8_t> data = {0x01};
    ASSERT_EQ(1, data.size());

    EXPECT_CALL(dbus, pingHothd(std::string_view(""))).WillOnce(Return(true));

    EXPECT_TRUE(hvn.open(session_, hvn.requiredFlags(), legacyPath));

    EXPECT_FALSE(hvn.write(session_, hvn.maxBufferSize(), data));
}

TEST_F(HothUpdateWriteTest, WritingFullBufferAtOffsetZeroSucceeds)
{
    // Test the case where you write the full buffer length at once to the 0th
    // offset.

    int bytes = hvn.maxBufferSize();
    std::vector<uint8_t> data = {0x01};
    data.resize(bytes);
    ASSERT_EQ(bytes, data.size());

    EXPECT_CALL(dbus, pingHothd(std::string_view(""))).WillOnce(Return(true));

    EXPECT_TRUE(hvn.open(session_, hvn.requiredFlags(), legacyPath));

    EXPECT_TRUE(hvn.write(session_, 0, data));
}

TEST_F(HothUpdateWriteTest, WritingOneByteToTheLastOffsetSucceeds)
{
    // Test the case where you write the last byte.

    std::vector<uint8_t> data = {0x01};
    ASSERT_EQ(1, data.size());

    EXPECT_CALL(dbus, pingHothd(std::string_view(""))).WillOnce(Return(true));

    EXPECT_TRUE(hvn.open(session_, hvn.requiredFlags(), legacyPath));

    EXPECT_TRUE(hvn.write(session_, (hvn.maxBufferSize() - 1), data));
}

} // namespace ipmi_hoth
