/**
 * Copyright © 2018 IBM 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 "policy_table.hpp"

#include <nlohmann/json.hpp>
#include <phosphor-logging/log.hpp>

#include <experimental/filesystem>
#include <fstream>

namespace ibm
{
namespace logging
{
namespace policy
{

namespace fs = std::experimental::filesystem;
using namespace phosphor::logging;

Table::Table(const std::string& jsonFile)
{
    if (fs::exists(jsonFile))
    {
        load(jsonFile);
    }
    else
    {
        log<level::INFO>("Policy table JSON file does not exist",
                         entry("FILE=%s", jsonFile.c_str()));
    }
}

void Table::load(const std::string& jsonFile)
{
    try
    {
        std::ifstream file{jsonFile};

        auto json = nlohmann::json::parse(file, nullptr, true);

        for (const auto& policy : json)
        {
            DetailsList detailsList;

            for (const auto& details : policy["dtls"])
            {
                Details d;
                d.modifier = details["mod"];
                d.msg = details["msg"];
                d.ceid = details["CEID"];
                detailsList.emplace_back(std::move(d));
            }
            policies.emplace(policy["err"], std::move(detailsList));
        }

        loaded = true;
    }
    catch (const std::exception& e)
    {
        log<level::ERR>("Failed loading policy table json file",
                        entry("FILE=%s", jsonFile.c_str()),
                        entry("ERROR=%s", e.what()));
        loaded = false;
    }
}

FindResult Table::find(const std::string& error,
                       const std::string& modifier) const
{
    // First find the entry based on the error, and then find which
    // underlying details object it is with the help of the modifier.

    auto policy = policies.find(error);

    if (policy != policies.end())
    {
        // If there is no exact modifier match, then look for an entry with
        // an empty modifier - it is the catch-all for that error.
        auto details = std::find_if(
            policy->second.begin(), policy->second.end(),
            [&modifier](const auto& d) { return modifier == d.modifier; });

        if ((details == policy->second.end()) && !modifier.empty())
        {
            details =
                std::find_if(policy->second.begin(), policy->second.end(),
                             [](const auto& d) { return d.modifier.empty(); });
        }

        if (details != policy->second.end())
        {
            return DetailsReference(*details);
        }
    }

    return {};
}
} // namespace policy
} // namespace logging
} // namespace ibm
