// 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
