// 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 "cli_parser.hpp"
#include "parser.hpp"
#include "payload_update_common.hpp"

#include <fstream>

#include <gtest/gtest.h>

namespace google::hoth::tools::payload_update
{
namespace
{
TEST(PayloadUpdateCLIParserTest, ParseSucceedsWithValidVersionCommand)
{
    const char* argv[] = {"exe", "-i", "gxc0", "version"};
    auto parser = std::make_unique<CLIParser>(sizeof(argv) / sizeof(argv[0]),
                                              (char**)argv);
    Args args;
    EXPECT_TRUE(parser->parse(args));
    EXPECT_EQ(argv[2], args.hothId);
    EXPECT_EQ(SubCommandType::kVersion, args.command);
}

TEST(PayloadUpdateCLIParserTest, ParseSucceedsWithValidUpdateCommand)
{
    const char* payloadPath = "payload_update_cli_parser_test_payload";
    const char* argv[] = {"exe",    "-i",        "vxc3",
                          "update", payloadPath, "--reset"};
    std::ofstream payloadFile(payloadPath, std::ios::binary);
    std::vector<uint8_t> bytes{0, 1, 2, 3, 4, 5, 6, 7};
    payloadFile.write(reinterpret_cast<char*>(bytes.data()), static_cast<int64_t>(bytes.size()));
    payloadFile.close();
    auto parser = std::make_unique<CLIParser>(sizeof(argv) / sizeof(argv[0]),
                                              (char**)argv);
    Args args;
    EXPECT_TRUE(parser->parse(args));
}

TEST(PayloadUpdateCLIParserTest, ParseSucceedsWithValidStaticWPUpdateCommand)
{
    const char* payloadPath = "payload_update_cli_parser_test_payload";
    const char* argv[] = {
        "exe", "-i", "vxc3", "update", payloadPath, "--reset", "-m", "1",
    };
    std::ofstream payloadFile(payloadPath, std::ios::binary);
    std::vector<uint8_t> bytes{0, 1, 2, 3, 4, 5, 6, 7};
    payloadFile.write(reinterpret_cast<char*>(bytes.data()),static_cast<int64_t>( bytes.size()));
    payloadFile.close();
    auto parser = std::make_unique<CLIParser>(sizeof(argv) / sizeof(argv[0]),
                                              (char**)argv);
    Args args;
    EXPECT_TRUE(parser->parse(args));
}

TEST(PayloadUpdateCLIParserTest, ParseFailsWithUpdateCommandIfFileDoesNotExist)
{
    const char* argv[] = {"exe",    "-i",         "vxc3",
                          "update", "iamnothere", "--reset"};
    auto parser = std::make_unique<CLIParser>(sizeof(argv) / sizeof(argv[0]),
                                              (char**)argv);
    Args args;
    EXPECT_FALSE(parser->parse(args));
}

TEST(PayloadUpdateCLIParserTest, ParseFailsWithInvalidCommandArguments)
{
    const char* argv[] = {"exe", "-i", "gxc3", "version", "update"};
    auto parser = std::make_unique<CLIParser>(sizeof(argv) / sizeof(argv[0]),
                                              (char**)argv);
    Args args;
    EXPECT_FALSE(parser->parse(args));
}
TEST(PayloadUpdateCLIParserTest, ParseFailsWithInvalidStaticWPArguments)
{
    const char* payloadPath = "payload_update_cli_parser_test_payload";
    const char* argv[] = {
        "exe", "-i", "vxc3", "update", payloadPath, "--reset", "-m", "2",
    };

    auto parser = std::make_unique<CLIParser>(sizeof(argv) / sizeof(argv[0]),
                                              (char**)argv);
    Args args;
    EXPECT_FALSE(parser->parse(args));
}

TEST(PayloadUpdateCLIParserTest, ParseReset)
{
    const char* payloadPath = "payload_update_cli_parser_test_payload";
    const char* argv[] = {"exe",    "-i",        "vxc3",
                          "update", payloadPath, "--reset"};
    std::ofstream payloadFile(payloadPath, std::ios::binary);
    std::vector<uint8_t> bytes{0, 1, 2, 3, 4, 5, 6, 7};
    payloadFile.write(reinterpret_cast<char*>(bytes.data()), static_cast<int64_t>(bytes.size()));
    payloadFile.close();
    auto parser = std::make_unique<CLIParser>(sizeof(argv) / sizeof(argv[0]),
                                              (char**)argv);
    Args args;
    EXPECT_TRUE(parser->parse(args));
    EXPECT_EQ(args.reset, ResetMode::kNeeded);
}

TEST(PayloadUpdateCLIParserTest, ParseNoReset)
{
    const char* payloadPath = "payload_update_cli_parser_test_payload";
    const char* argv[] = {"exe", "-i", "vxc3", "update", payloadPath};
    std::ofstream payloadFile(payloadPath, std::ios::binary);
    std::vector<uint8_t> bytes{0, 1, 2, 3, 4, 5, 6, 7};
    payloadFile.write(reinterpret_cast<char*>(bytes.data()), static_cast<int64_t>(bytes.size()));
    payloadFile.close();
    auto parser = std::make_unique<CLIParser>(sizeof(argv) / sizeof(argv[0]),
                                              (char**)argv);
    Args args;
    EXPECT_TRUE(parser->parse(args));
    EXPECT_EQ(args.reset, ResetMode::kNever);
}

TEST(PayloadUpdateCLIParserTest, ParseResetIgnore)
{
    const char* payloadPath = "payload_update_cli_parser_test_payload";
    const char* argv[] = {"exe",       "-i",      "vxc3",       "update",
                          payloadPath, "--reset", "ignore_fail"};
    std::ofstream payloadFile(payloadPath, std::ios::binary);
    std::vector<uint8_t> bytes{0, 1, 2, 3, 4, 5, 6, 7};
    payloadFile.write(reinterpret_cast<char*>(bytes.data()), static_cast<int64_t>(bytes.size()));
    payloadFile.close();
    auto parser = std::make_unique<CLIParser>(sizeof(argv) / sizeof(argv[0]),
                                              (char**)argv);
    Args args;
    EXPECT_TRUE(parser->parse(args));
    EXPECT_EQ(args.reset, ResetMode::kIgnore);
}

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