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

#include <stdio.h>

#include <filesystem>

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

namespace google::hoth::tools
{
namespace
{

using ::testing::_;
using ::testing::Return;

class HothUpdaterCLIMock : public HothUpdaterCLI
{
  public:
    MOCK_METHOD(HothVersionStringsRsp, getHothVersion,
                (sdbusplus::bus::bus & bus, std::string_view hoth_id));
    MOCK_METHOD(HothActivationStatistics, getHothActivationStatistics,
                (sdbusplus::bus::bus & bus, std::string_view hoth_id));
    MOCK_METHOD(void, spiWrite,
                (sdbusplus::bus::bus&, std::string_view,
                 const std::span<const uint8_t>, std::optional<uint32_t>));
    MOCK_METHOD(std::vector<uint8_t>, readFileIntoByteArray,
                (std::string_view));
    MOCK_METHOD(FirmwareUpdateStatus, getFirmwareUpdateStatus,
                (sdbusplus::bus::bus & bus, std::string_view hoth_id));
};

TEST(PayloadUpdateCLITest, splitStringTest)
{
    std::vector<std::string> sp = splitString("", ',');
    EXPECT_EQ(sp.size(), 0);

    sp = splitString("product_3_1", ',');
    EXPECT_EQ(sp.size(), 1);
    EXPECT_EQ(sp[0], "product_3_1");

    sp = splitString("product_3_1,product_3_2", ',');
    EXPECT_EQ(sp.size(), 2);
    EXPECT_EQ(sp[0], "product_3_1");
    EXPECT_EQ(sp[1], "product_3_2");
}

class HothUpdaterCLITest : public ::testing::Test
{
  protected:
    HothUpdaterCLIMock cli;
};

// Test for making sure doActivationCheck does not error out
TEST_F(HothUpdaterCLITest, doActivationCheckTest)
{
    HothVersionStringsRsp rsp = {.header =
                                     {
                                         .struct_version = 0,
                                         .checksum = 0,
                                         .result = 0,
                                         .data_len = 0,
                                         .reserved = 0,
                                     },
                                 .version = {
                                     .version_string_ro = "1.2.345",
                                     .version_string_rw = "2.3.456",
                                     .reserved = "",
                                     .current_image = 0,
                                 }};
    Args args;
    args.expectedRwVersion = "2.3.456";
    EXPECT_CALL(cli, getHothVersion(_, _)).Times(1).WillOnce(Return(rsp));
    EXPECT_CALL(cli, getHothActivationStatistics(_, _)).Times(0);
    cli.doActivationCheck(args);
}

// Test doActivationCheck when version mismatch.
TEST_F(HothUpdaterCLITest, doActivationCheckWrongVersion)
{
    HothVersionStringsRsp rsp = {.header =
                                     {
                                         .struct_version = 0,
                                         .checksum = 0,
                                         .result = 0,
                                         .data_len = 0,
                                         .reserved = 0,
                                     },
                                 .version = {
                                     .version_string_ro = "1.2.345",
                                     .version_string_rw = "2.3.456",
                                     .reserved = "",
                                     .current_image = 0,
                                 }};
    HothActivationStatistics stats = {
        .rw_failure_code = 1,
        .rw_failed_minor = 2,
        .ro_failure_code = 0xffff,
        .reset_flags = 3,
        .uptime_us = 0xdeadbeeffeedbead,
    };
    Args args;
    args.expectedRwVersion = "3.4.567";
    EXPECT_CALL(cli, getHothVersion(_, _)).Times(1).WillOnce(Return(rsp));
    EXPECT_CALL(cli, getHothActivationStatistics(_, _))
        .Times(1)
        .WillOnce(Return(stats));
    EXPECT_THROW(cli.doActivationCheck(args), std::runtime_error);
}

// Test for making sure the doUpdate loop works correctly
TEST_F(HothUpdaterCLITest, getFirmwareUpdateStatusTest)
{
    Args args;
    args.updateMethod = "spi";
    args.imageFilename = "dummy";

    std::vector<uint8_t> dummy_image = {0, 1, 2, 3};
    EXPECT_CALL(cli, readFileIntoByteArray(_))
        .Times(1)
        .WillOnce(Return(dummy_image));

    EXPECT_CALL(cli, spiWrite(_, _, _, _)).Times(1);

    EXPECT_CALL(cli, getFirmwareUpdateStatus(_, _))
        .Times(3)
        .WillOnce(Return(FirmwareUpdateStatus::InProgress))
        .WillOnce(Return(FirmwareUpdateStatus::InProgress))
        .WillOnce(Return(FirmwareUpdateStatus::Done));

    cli.doUpdate(args);
}

} // namespace

} // namespace google::hoth::tools
