// 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>
#include <string_view>
#include <vector>

#include <gmock/gmock.h>

using ::testing::_;
using ::testing::ContainerEq;
using ::testing::IsEmpty;
using ::testing::NotNull;
using ::testing::Return;

using namespace std::literals;

namespace ipmi_hoth
{

using Cb = internal::DbusUpdate::Cb;
using FirmwareUpdateStatus = internal::DbusUpdate::FirmwareUpdateStatus;

class HothUpdateCommitTest : public HothUpdateTest
{
  protected:
    template <typename Req>
    void expectUpdate(std::string_view hothId, Req&& req)
    {
        EXPECT_CALL(dbus, UpdateFirmware(hothId, req, _))
            .WillOnce(
                [&](std::string_view, const std::vector<uint8_t>&, Cb&& icb) {
                    cb = std::move(icb);
                    return stdplus::Cancel(std::nullopt);
                });
    }

    Cb cb;
};

const auto static test_str = "Hello,\0 world!"s;
const std::vector<uint8_t> static test_buf(test_str.begin(), test_str.end());

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

    EXPECT_FALSE(hvn.commit(session_, std::vector<uint8_t>()));
}

TEST_F(HothUpdateCommitTest, NonEmptyDataParamFails)
{
    // Verify that we do not accept any data passed into the commit call.

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

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

    EXPECT_FALSE(hvn.commit(session_, std::vector<uint8_t>({1, 2, 3})));
}

TEST_F(HothUpdateCommitTest, DbusExceptionSetsCommitErrorStateAndFails)
{
    // Verify that when the dbus call hits an exception, commit method fails
    // and that the state is set to blobs::StateFlags::commit_error

    EXPECT_CALL(dbus, pingHothd(std::string_view(""))).WillOnce(Return(true));
    expectUpdate(/*hothId=*/"", ContainerEq(test_buf));

    EXPECT_TRUE(hvn.open(session_, hvn.requiredFlags(), legacyPath));
    // session, offset, data
    EXPECT_TRUE(hvn.write(session_, 0, test_buf));
    EXPECT_TRUE(hvn.commit(session_, std::vector<uint8_t>()));
    cb(FirmwareUpdateStatus::Error);

    blobs::BlobMeta meta;
    EXPECT_TRUE(hvn.stat(session_, &meta));

    EXPECT_EQ(meta.blobState,
              blobs::StateFlags::open_write | blobs::StateFlags::commit_error);
}

TEST_F(HothUpdateCommitTest, EmptyBufferCommitLegacyHothSuccessful)
{
    // Verify that we are able to succssfully commit an empty buffer

    EXPECT_CALL(dbus, pingHothd(std::string_view(""))).WillOnce(Return(true));
    expectUpdate(/*hothId=*/"", IsEmpty());

    EXPECT_TRUE(hvn.open(session_, hvn.requiredFlags(), legacyPath));
    // No write call to populate the buffer here
    EXPECT_TRUE(hvn.commit(session_, std::vector<uint8_t>()));
    cb(FirmwareUpdateStatus::Done);

    blobs::BlobMeta meta;
    EXPECT_TRUE(hvn.stat(session_, &meta));

    EXPECT_EQ(meta.size, 0);
    EXPECT_EQ(meta.blobState,
              blobs::StateFlags::open_write | blobs::StateFlags::committed);
}

TEST_F(HothUpdateCommitTest, EmptyBufferCommitNamedHothSuccessful)
{
    // Verify that we are able to succssfully commit an empty buffer

    EXPECT_CALL(dbus, pingHothd(std::string_view(name))).WillOnce(Return(true));
    expectUpdate(/*hothId=*/name, IsEmpty());

    EXPECT_TRUE(hvn.open(session_, hvn.requiredFlags(), namedPath));
    // No write call to populate the buffer here
    EXPECT_TRUE(hvn.commit(session_, std::vector<uint8_t>()));
    cb(FirmwareUpdateStatus::Done);

    blobs::BlobMeta meta;
    EXPECT_TRUE(hvn.stat(session_, &meta));

    EXPECT_EQ(meta.size, 0);
    EXPECT_EQ(meta.blobState,
              blobs::StateFlags::open_write | blobs::StateFlags::committed);
}

TEST_F(HothUpdateCommitTest, NonEmptyBufferCommitSuccessful)
{
    // Verify that we are able to succssfully commit a buffer with valid data

    EXPECT_CALL(dbus, pingHothd(std::string_view(""))).WillOnce(Return(true));
    expectUpdate(/*hothId=*/"", ContainerEq(test_buf));

    EXPECT_TRUE(hvn.open(session_, hvn.requiredFlags(), legacyPath));
    // session, offset, data
    EXPECT_TRUE(hvn.write(session_, 0, test_buf));
    EXPECT_TRUE(hvn.commit(session_, std::vector<uint8_t>()));
    cb(FirmwareUpdateStatus::Done);

    blobs::BlobMeta meta;
    EXPECT_TRUE(hvn.stat(session_, &meta));

    EXPECT_EQ(meta.size, test_buf.size());
    EXPECT_EQ(meta.blobState,
              blobs::StateFlags::open_write | blobs::StateFlags::committed);
}

TEST_F(HothUpdateCommitTest, IdempotentSuccess)
{
    // Verify that repeated successful commits only result in one D-Bus call

    EXPECT_CALL(dbus, pingHothd(std::string_view(""))).WillOnce(Return(true));
    expectUpdate(/*hothId=*/"", IsEmpty());

    EXPECT_TRUE(hvn.open(session_, hvn.requiredFlags(), legacyPath));
    // No write call to populate the buffer here

    // These calls will return due to the state being "committing". Calling
    // stat is the only way to check if the state has changed to "committed"
    EXPECT_TRUE(hvn.commit(session_, std::vector<uint8_t>()));
    EXPECT_TRUE(hvn.commit(session_, std::vector<uint8_t>()));
    cb(FirmwareUpdateStatus::Done);
    EXPECT_TRUE(hvn.commit(session_, std::vector<uint8_t>()));

    blobs::BlobMeta meta;
    EXPECT_TRUE(hvn.stat(session_, &meta));

    // These calls will return due to the state being "committed"
    EXPECT_TRUE(hvn.commit(session_, std::vector<uint8_t>()));
    EXPECT_TRUE(hvn.commit(session_, std::vector<uint8_t>()));

    // Stat is also idempotent, no need to mock the D-Bus call here
    EXPECT_TRUE(hvn.stat(session_, &meta));

    EXPECT_EQ(meta.size, 0);
    EXPECT_EQ(meta.blobState,
              blobs::StateFlags::open_write | blobs::StateFlags::committed);
}

TEST_F(HothUpdateCommitTest, ErrorRetry)
{
    // Verify that commit after error retries the update D-Bus call

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

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

    // These calls will return due to the state being "commit_error"
    expectUpdate(/*hothId=*/"", IsEmpty());
    EXPECT_TRUE(hvn.commit(session_, std::vector<uint8_t>()));
    cb(FirmwareUpdateStatus::Error);
    expectUpdate(/*hothId=*/"", IsEmpty());
    EXPECT_TRUE(hvn.commit(session_, std::vector<uint8_t>()));
    cb(FirmwareUpdateStatus::Error);
    expectUpdate(/*hothId=*/"", IsEmpty());
    EXPECT_TRUE(hvn.commit(session_, std::vector<uint8_t>()));
    cb(FirmwareUpdateStatus::Error);

    blobs::BlobMeta meta;
    EXPECT_TRUE(hvn.stat(session_, &meta));

    EXPECT_EQ(meta.blobState,
              blobs::StateFlags::open_write | blobs::StateFlags::commit_error);
}

} // namespace ipmi_hoth
