// 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 "dbus_interface.hpp"
#include "fake_bus.hpp"
#include "fake_parser.hpp"
#include "parser.hpp"
#include "payload_update_cli.hpp"
#include "payload_update_common.hpp"

#include <gtest/gtest.h>

namespace google::hoth::tools::payload_update
{
namespace
{
TEST(PayloadUpdateCLITest, UpdateSucceedsOnNormalPayloadUpdateFlow)
{
    fake_bus::Options options;
    options.resetRequired = true;
    auto parser = std::make_unique<FakeParser>();
    auto bus = std::make_unique<FakeBus>(options);
    auto localParser = parser.get();
    auto cli =
        std::make_unique<PayloadUpdateCLI>(std::move(parser), std::move(bus));
    Args args;
    args.hothId = "vxc0";
    args.command = SubCommandType::kUpdate;
    args.payloadFilename = "iampayload";
    args.reset = ResetMode::kNeeded;
    localParser->inject(args);
    EXPECT_TRUE(cli->getOptions());
    EXPECT_TRUE(cli->execute());
}

TEST(PayloadUpdateCLITest, UpdateSucceedsOnNormalStaticWPPayloadUpdateFlow)
{
    fake_bus::Options options;
    options.resetRequired = true;
    auto parser = std::make_unique<FakeParser>();
    auto bus = std::make_unique<FakeBus>(options);
    auto localParser = parser.get();
    auto cli =
        std::make_unique<PayloadUpdateCLI>(std::move(parser), std::move(bus));
    Args args;
    args.hothId = "vxc0";
    args.command = SubCommandType::kUpdate;
    args.payloadFilename = "iampayload";
    args.reset = ResetMode::kNeeded;
    args.payloadUpdateMode = UpdateMode::kUpdateStaticWPRegions;
    localParser->inject(args);
    EXPECT_TRUE(cli->getOptions());
    EXPECT_TRUE(cli->execute());
}

TEST(PayloadUpdateCLITest, UpdateFailsWhenResetNotHeldDuringPayloadUpdateFlow)
{
    fake_bus::Options options;
    options.resetRequired = true;
    auto parser = std::make_unique<FakeParser>();
    auto bus = std::make_unique<FakeBus>(options);
    auto localParser = parser.get();
    auto cli =
        std::make_unique<PayloadUpdateCLI>(std::move(parser), std::move(bus));
    Args args;
    args.hothId = "vxc1";
    args.command = SubCommandType::kUpdate;
    args.payloadFilename = "iampayload";
    args.reset = ResetMode::kNever;
    args.spsPassthrough = true;
    localParser->inject(args);
    EXPECT_TRUE(cli->getOptions());
    EXPECT_FALSE(cli->execute());
}

TEST(PayloadUpdateCLITest, UpdateSucceedsWhenResetNotHeldButNotRequired)
{
    fake_bus::Options options;
    auto parser = std::make_unique<FakeParser>();
    auto bus = std::make_unique<FakeBus>(options);
    auto localParser = parser.get();
    auto cli =
        std::make_unique<PayloadUpdateCLI>(std::move(parser), std::move(bus));
    Args args;
    args.hothId = "gxc1";
    args.command = SubCommandType::kUpdate;
    args.payloadFilename = "iampayload";
    args.reset = ResetMode::kNever;
    args.spsPassthrough = true;
    localParser->inject(args);
    EXPECT_TRUE(cli->getOptions());
    EXPECT_TRUE(cli->execute());
}

TEST(PayloadUpdateCLITest, UpdateFailsOnInjectedInvalidStagingAreaSizeFlag)
{
    fake_bus::Options options;
    options.resetRequired = true;
    options.injectInvalidAreaSize = true;
    auto parser = std::make_unique<FakeParser>();
    auto bus = std::make_unique<FakeBus>(options);
    auto localParser = parser.get();
    auto cli =
        std::make_unique<PayloadUpdateCLI>(std::move(parser), std::move(bus));
    Args args;
    args.hothId = "vxc0";
    args.command = SubCommandType::kUpdate;
    args.payloadFilename = "iampayload";
    args.reset = ResetMode::kNeeded;
    args.spsPassthrough = true;
    localParser->inject(args);
    EXPECT_TRUE(cli->getOptions());
    EXPECT_FALSE(cli->execute());
}

TEST(PayloadUpdateCLITest, UpdateFailsOnInjectedSendPayloadFlag)
{
    fake_bus::Options options;
    options.resetRequired = true;
    options.injectPayloadFail = true;
    auto parser = std::make_unique<FakeParser>();
    auto bus = std::make_unique<FakeBus>(options);
    auto localParser = parser.get();
    auto cli =
        std::make_unique<PayloadUpdateCLI>(std::move(parser), std::move(bus));
    Args args;
    args.hothId = "vxc3";
    args.command = SubCommandType::kUpdate;
    args.payloadFilename = "iampayload";
    args.reset = ResetMode::kNeeded;
    args.spsPassthrough = true;
    localParser->inject(args);
    EXPECT_TRUE(cli->getOptions());
    EXPECT_FALSE(cli->execute());
}

TEST(PayloadUpdateCLITest, GetVersionAPIReturnsExpectedString)
{
    fake_bus::Options options;
    options.newVersion = "3.0.0.0";
    auto parser = std::make_unique<FakeParser>();
    auto bus = std::make_unique<FakeBus>(options);
    auto localParser = parser.get();
    auto localBus = bus.get();
    auto cli =
        std::make_unique<PayloadUpdateCLI>(std::move(parser), std::move(bus));
    Args args;
    args.hothId = "vxc0";
    args.command = SubCommandType::kUpdate;
    args.payloadFilename = "iampayload";
    args.spsPassthrough = true;
    localParser->inject(args);
    EXPECT_TRUE(cli->getOptions());
    EXPECT_TRUE(cli->execute());
    args.command = SubCommandType::kVersion;
    localParser->inject(args);
    EXPECT_TRUE(cli->getOptions());
    EXPECT_TRUE(cli->execute());
    auto nextVersion =
        localBus->getPayloadVersion(args.hothId, VersionType::kNextHalf);
    EXPECT_EQ(*nextVersion, options.newVersion);
}

TEST(PayloadUpdateCLITest, UpdateFailsOnInjectedSpsPassthroughFailure)
{
    fake_bus::Options options;
    options.resetRequired = false;
    options.injectSpsPassthroughFail = true;
    auto parser = std::make_unique<FakeParser>();
    auto bus = std::make_unique<FakeBus>(options);
    auto localParser = parser.get();
    auto cli =
        std::make_unique<PayloadUpdateCLI>(std::move(parser), std::move(bus));
    Args args;
    args.hothId = "vxc3";
    args.command = SubCommandType::kUpdate;
    args.payloadFilename = "iampayload";
    args.reset = ResetMode::kNeeded;
    args.spsPassthrough = true;
    localParser->inject(args);
    EXPECT_TRUE(cli->getOptions());
    EXPECT_FALSE(cli->execute());
}

} // namespace
} // namespace google::hoth::tools::payload_update
