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