// 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 <CLI/CLI.hpp>

#include <unordered_map>

namespace google::hoth::tools
{
bool CLIParser::parse(payload_update::Args& argsOut)
{
    CLI::App app;
    argsOut.command = payload_update::SubCommandType::kNop;
    app.set_help_all_flag("--help-all", "Expand all help");
    app.add_option("--hoth_instance, -i", argsOut.hothId, "Hoth instance name");
    // Enforce accepting only one of the following sub-commands
    app.require_subcommand(1);
    auto* version = app.add_subcommand("version", "Get active payload version");
    version->add_flag("--next, -n", "Optional: Get next half version instead");
    auto* update = app.add_subcommand("update", "Update payload");
    update->add_option("filename", argsOut.payloadFilename, "Path to payload")
        ->required()
        ->check(CLI::ExistingFile);
    std::unordered_map<std::string, payload_update::ResetMode> resetMap{
        {"never", payload_update::ResetMode::kNever},
        {"", payload_update::ResetMode::kNeeded},
        {"needed", payload_update::ResetMode::kNeeded},
        {"ignore_fail", payload_update::ResetMode::kIgnore}};
    argsOut.reset = payload_update::ResetMode::kNever;
    update
        ->add_option("--reset, -r", argsOut.reset,
                     "Put target in reset during update and pull target out of"
                     " reset after update")
        ->transform(CLI::CheckedTransformer(resetMap))
        ->expected(0, 1);
    argsOut.spsPassthrough = false;
    update->add_flag("--sps_passthrough, -s", argsOut.spsPassthrough,
                     "Disable SPS passthrough during payload update and"
                     " re-enable it afterwards");
    std::unordered_map<std::string, payload_update::UpdateMode> updateMap{
        {"update_all", payload_update::UpdateMode::kUpdateAll},
        {"update_static_wp",
        payload_update::UpdateMode::kUpdateStaticWPRegions}};
    argsOut.payloadUpdateMode = payload_update::UpdateMode::kUpdateAll;
    update->add_option("--payloadUpdateMode, -m", argsOut.payloadUpdateMode,
                     "Erase entire partition for payload update or " 
                     "just Static & WP sections")
            ->transform(CLI::CheckedTransformer(updateMap))
            ->expected(0, 1);
    try
    {
        app.parse(argc, argv);
    }
    catch (const CLI::ParseError& e)
    {
        // If cli app exit with non-zero error code, it's a real parse error.
        // Otherwise, it's the '-h' help option and we should return gracefully.
        return app.exit(e) == 0;
    }
    if (version->count())
    {
        argsOut.command = payload_update::SubCommandType::kVersion;
        argsOut.versionType = payload_update::VersionType::kActiveHalf;
        if (version->count("--next") || version->count("-n"))
        {
            argsOut.versionType = payload_update::VersionType::kNextHalf;
        }
    }
    else if (update->count())
    {
        argsOut.command = payload_update::SubCommandType::kUpdate;
    }
    return true;
}
} // namespace google::hoth::tools
