// Copyright 2021 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 <flashupdate/args.hpp>
#include <flashupdate/info.hpp>
#include <flashupdate/logging.hpp>
#include <flashupdate/version.hpp>
#include <nlohmann/json.hpp>

#include <charconv>
#include <format>
#include <memory>
#include <span>
#include <string>

namespace flashupdate
{
namespace info
{

/** @brief Helper to print debug message or std output
 *
 * @param[in] message   Main message
 * @param[in] output    Print the message as std output with no debug
 * message
 */
static void print(const std::string& message, bool output)
{
    if (!output)
    {
        return;
    }
    STDLOG("{}", message);
}

std::string bytesToHex(std::span<const uint8_t> hash)
{
    std::string out;
    for (uint8_t num : hash)
    {
        std::format_to(std::back_inserter(out), "{:02x}", num);
    }
    return out;
}

std::string listStates()
{
    std::string out;
    for (const auto& [state, _] : info::stringToState)
    {
        std::format_to(std::back_inserter(out), "  `{}`\n", state);
    }
    return out;
}

std::string printUpdateInfo(const Args& args, struct UpdateInfo info)
{
    nlohmann::json output;
    if (args.checkStagedVersion)
    {

        output["Staged Version"] = info.stage.format();
        print(output["Staged Version"], args.cleanOutput);
    }

    if (args.checkActiveVersion)
    {
        output["Active Version"] = info.active.format();
        print(output["Active Version"], args.cleanOutput);
    }

    if (args.checkStageState)
    {
        auto findState = stateToString.find(info.state);
        std::string_view state = "CORRUPTED";
        if (findState != stateToString.end())
        {
            state = findState->second;
        }

        output["Staged State"] = state;
        print(output["Staged State"], args.cleanOutput);
    }

    if (args.checkStagedIndex)
    {
        output["Staged Index"] = std::to_string(info.stagingIndex);
        print(output["Staged Index"], args.cleanOutput);
    }

    if (args.otherInfo)
    {
        output["Stage CR51 Descriptor Hash"] =
            bytesToHex(std::span<const uint8_t>(&info.stageDescriptor.hash[0],
                                                &info.stageDescriptor.hash[0] +
                                                    SHA256_DIGEST_LENGTH));
        print(output["Stage CR51 Descriptor Hash"], args.cleanOutput);
    }

    std::string outputStr = output.dump();

    LOG(LogLevel::Notice, "{}", outputStr);
    return outputStr;
}

nlohmann::json UpdateInfo::json()
{
    nlohmann::json output;
    output["Staged Version"] = stage.format();
    output["Active Version"] = active.format();
    auto findState = stateToString.find(state);
    if (findState == stateToString.end())
    {
        output["Staged State"] = "CORRUPTED";
    }
    else
    {
        output["Staged State"] = findState->second;
    }
    output["Staged Index"] = std::to_string(stagingIndex);
    output["Stage CR51 Descriptor Hash"] = bytesToHex(std::span<const uint8_t>(
        &stageDescriptor.hash[0],
        &stageDescriptor.hash[0] + SHA256_DIGEST_LENGTH));
    return output;
}

} // namespace info
} // namespace flashupdate
