/*
// Copyright (c) 2019 Intel Corporation
//
// 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 "post_code.hpp"

#include <cereal/access.hpp>
#include <cereal/archives/binary.hpp>
#include <cereal/cereal.hpp>
#include <cereal/types/map.hpp>
#include <cereal/types/tuple.hpp>
#include <cereal/types/vector.hpp>
#include <phosphor-logging/commit.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/exception.hpp>

#include <iomanip>

using nlohmann::json;

const static constexpr auto timeoutMicroSeconds = 1000000;
/* systemd service to kick start a target. */
constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1";
constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";

void PostCodeEvent::raise() const
{
    json j = {{name, args}};
    try
    {
        sdbusplus::exception::throw_via_json(j);
    }
    catch (sdbusplus::exception::generated_event_base& e)
    {
        auto path = lg2::commit(std::move(e));
        std::cout << path.str << std::endl;
    }
}

void from_json(const json& j, PostCodeEvent& event)
{
    j.at("name").get_to(event.name);
    for (const auto& entry : j.at("arguments").items())
    {
        if (entry.value().is_string())
        {
            event.args[entry.key()] = entry.value().get<std::string>();
        }
        else if (entry.value().is_number_integer())
        {
            event.args[entry.key()] = entry.value().get<int>();
        }
    }
}

std::vector<uint8_t> decodeHexString(const std::string& hex)
{
    std::vector<uint8_t> out;
    // The post-code is at least 1 byte. So, we need at
    // least a 4 char string.
    if (hex.size() < 4 || hex.size() % 2 != 0 || hex.substr(0, 2) != "0x")
    {
        throw std::runtime_error("Bad Hex String: " + hex);
    }
    for (size_t i = 2; i < hex.size(); i += 2)
    {
        std::string byteString = hex.substr(i, 2);
        uint8_t byte = (uint8_t)std::strtol(byteString.c_str(), NULL, 16);
        out.push_back(byte);
    }
    return out;
}

void from_json(const json& j, PostCodeHandler& handler)
{
    std::string primary;
    j.at("name").get_to(handler.name);
    j.at("description").get_to(handler.description);
    j.at("primary").get_to(primary);
    handler.primary = decodeHexString(primary);
    if (j.contains("secondary"))
    {
        std::string secondary;
        j.at("secondary").get_to(secondary);
        handler.secondary = decodeHexString(secondary);
    }
    if (j.contains("targets"))
    {
        j.at("targets").get_to(handler.targets);
    }
    if (j.contains("event"))
    {
        PostCodeEvent event;
        j.at("event").get_to(event);
        handler.event = event;
    }
}

const PostCodeHandler* PostCodeHandlers::find(postcode_t code)
{
    for (const auto& handler : handlers)
    {
        if (handler.primary == std::get<0>(code) &&
            (!handler.secondary || *handler.secondary == std::get<1>(code)))
        {
            return &handler;
        }
    }
    return nullptr;
}

void PostCodeHandlers::handle(postcode_t code)
{
    const PostCodeHandler* handler = find(code);
    if (!handler)
    {
        return;
    }
    for (const auto& target : handler->targets)
    {
        auto bus = sdbusplus::bus::new_default();
        auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
                                          SYSTEMD_INTERFACE, "StartUnit");
        method.append(target);
        method.append("replace");
        bus.call_noreply(method);
    }
    if (handler->event)
    {
        (*(handler->event)).raise();
    }
}

void PostCodeHandlers::load(const std::string& path)
{
    std::ifstream ifs(path);
    handlers = json::parse(ifs).template get<std::vector<PostCodeHandler>>();
    ifs.close();
}

void PostCode::deleteAll()
{
    std::uintmax_t n = fs::remove_all(postCodeListPath);
    std::cerr << "clearPostCodes deleted " << n << " files in "
              << postCodeListPath << std::endl;
    fs::create_directories(postCodeListPath);
    postCodes.clear();
    currentBootCycleIndex = 0;
    currentBootCycleCount(0);
}

std::vector<postcode_t> PostCode::getPostCodes(uint16_t index)
{
    std::vector<postcode_t> codesVec;
    if (1 == index && !postCodes.empty())
    {
        std::transform(postCodes.begin(), postCodes.end(),
                       std::back_inserter(codesVec),
                       [](const auto& kv) { return kv.second; });
    }
    else
    {
        uint16_t bootNum = getBootNum(index);

        decltype(postCodes) codes;
        deserializePostCodes(postCodeListPath / std::to_string(bootNum), codes);
        std::transform(codes.begin(), codes.end(), std::back_inserter(codesVec),
                       [](const auto& kv) { return kv.second; });
    }
    return codesVec;
}

std::map<uint64_t, postcode_t> PostCode::getPostCodesWithTimeStamp(
    uint16_t index)
{
    if (1 == index && !postCodes.empty())
    {
        return postCodes;
    }

    uint16_t bootNum = getBootNum(index);
    decltype(postCodes) codes;
    deserializePostCodes(postCodeListPath / std::to_string(bootNum), codes);
    return codes;
}

void PostCode::savePostCodes(postcode_t code)
{
    if (!timer)
    {
        timer = std::make_unique<sdbusplus::Timer>(event.get(), [this]() {
            serialize(postCodeListPath);
        });
    }

    // steady_clock is a monotonic clock that is guaranteed to never be adjusted
    auto postCodeTimeSteady = std::chrono::steady_clock::now();
    uint64_t tsUS = std::chrono::duration_cast<std::chrono::microseconds>(
                        std::chrono::system_clock::now().time_since_epoch())
                        .count();

    if (postCodes.empty())
    {
        firstPostCodeTimeSteady = postCodeTimeSteady;
        firstPostCodeUsSinceEpoch = tsUS; // uS since epoch for 1st post code
        incrBootCycle();
    }
    else
    {
        // calculating tsUS so it is monotonic within the same boot
        tsUS = firstPostCodeUsSinceEpoch +
               std::chrono::duration_cast<std::chrono::microseconds>(
                   postCodeTimeSteady - firstPostCodeTimeSteady)
                   .count();
    }

    postCodes.insert(std::make_pair(tsUS, code));
    if (postCodes.size() > MAX_POST_CODE_SIZE_PER_CYCLE)
    {
        postCodes.erase(postCodes.begin());
    }

    if (!timer->isRunning())
    {
        timer->start(std::chrono::microseconds(timeoutMicroSeconds));
    }

    if (strlen(POSTCODE_DISPLAY_PATH) > 0)
    {
        std::string postCodeDisplayPath =
            POSTCODE_DISPLAY_PATH + std::to_string(node);

        std::ofstream postCodeDisplayFile(postCodeDisplayPath);
        postCodeDisplayFile << "0x" << std::setfill('0') << std::hex;
        for (const auto& byte : std::get<0>(code))
        {
            postCodeDisplayFile << std::setw(2) << static_cast<int>(byte);
        }
        postCodeDisplayFile.close();
    }

#ifdef ENABLE_BIOS_POST_CODE_LOG
    uint64_t usTimeOffset = tsUS - firstPostCodeUsSinceEpoch;
    std::ostringstream hexCode;
    hexCode << "0x" << std::setfill('0') << std::hex;
    for (const auto& byte : std::get<0>(code))
    {
        hexCode << std::setw(2) << static_cast<int>(byte);
    }

    std::ostringstream timeOffsetStr;
    // Set Fixed-Point Notation
    timeOffsetStr << std::fixed;
    // Set precision to 4 digits
    timeOffsetStr << std::setprecision(4);
    // Add double to stream
    timeOffsetStr << static_cast<double>(usTimeOffset) / 1000 / 1000;

    phosphor::logging::log<phosphor::logging::level::INFO>(
        "BIOS POST Code",
        phosphor::logging::entry("REDFISH_MESSAGE_ID=%s",
                                 "OpenBMC.0.2.BIOSPOSTCode"),
        phosphor::logging::entry(
            "REDFISH_MESSAGE_ARGS=%d,%s,%s", currentBootCycleIndex,
            timeOffsetStr.str().c_str(), hexCode.str().c_str()));
#endif
    postCodeHandlers.handle(code);

    return;
}

fs::path PostCode::serialize(const fs::path& path)
{
    try
    {
        std::ofstream osIdx(path / CurrentBootCycleIndexName, std::ios::binary);
        cereal::BinaryOutputArchive idxArchive(osIdx);
        idxArchive(currentBootCycleIndex);

        uint16_t count = currentBootCycleCount();
        std::ofstream osCnt(path / CurrentBootCycleCountName, std::ios::binary);
        cereal::BinaryOutputArchive cntArchive(osCnt);
        cntArchive(count);

        std::ofstream osPostCodes(path / std::to_string(currentBootCycleIndex));
        cereal::BinaryOutputArchive oarchivePostCodes(osPostCodes);
        oarchivePostCodes(postCodes);

        std::ofstream osVersion(path / PostCodeDataVersionName,
                                std::ios::binary);
        cereal::BinaryOutputArchive versionArchive(osVersion);
        versionArchive(PostCodeDataVersion);
    }
    catch (const cereal::Exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
        return "";
    }
    catch (const fs::filesystem_error& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
        return "";
    }
    return path;
}

bool PostCode::deserialize(const fs::path& path, uint16_t& index)
{
    try
    {
        if (fs::exists(path))
        {
            std::ifstream is(path, std::ios::in | std::ios::binary);
            cereal::BinaryInputArchive iarchive(is);
            iarchive(index);
            return true;
        }
        return false;
    }
    catch (const cereal::Exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
        return false;
    }
    catch (const fs::filesystem_error& e)
    {
        return false;
    }

    return false;
}

bool PostCode::deserializePostCodes(const fs::path& path,
                                    std::map<uint64_t, postcode_t>& codes)
{
    try
    {
        if (fs::exists(path))
        {
            std::ifstream is(path, std::ios::in | std::ios::binary);
            cereal::BinaryInputArchive iarchive(is);
            iarchive(codes);
            return true;
        }
        return false;
    }
    catch (const cereal::Exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
        return false;
    }
    catch (const fs::filesystem_error& e)
    {
        return false;
    }
    return false;
}

void PostCode::incrBootCycle()
{
    if (currentBootCycleIndex >= maxBootCycleNum())
    {
        currentBootCycleIndex = 1;
    }
    else
    {
        currentBootCycleIndex++;
    }
    currentBootCycleCount(std::min(
        maxBootCycleNum(), static_cast<uint16_t>(currentBootCycleCount() + 1)));
}

uint16_t PostCode::getBootNum(const uint16_t index) const
{
    // bootNum assumes the oldest archive is boot number 1
    // and the current boot number equals bootCycleCount
    // map bootNum back to bootIndex that was used to archive postcode
    uint16_t bootNum = currentBootCycleIndex;
    if (index > bootNum) // need to wrap around
    {
        bootNum = (maxBootCycleNum() + currentBootCycleIndex) - index + 1;
    }
    else
    {
        bootNum = currentBootCycleIndex - index + 1;
    }
    return bootNum;
}
