/**
 * Copyright © 2020 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 "profile.hpp"

#include "sdbusplus.hpp"

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

#include <algorithm>
#include <iterator>
#include <numeric>

namespace phosphor::fan::control::json
{

using json = nlohmann::json;
using namespace phosphor::logging;

// String key must be in all lowercase for method lookup
const std::map<std::string, methodHandler> Profile::_methods = {
    {"all_of", Profile::allOf}};

Profile::Profile(const json& jsonObj) : ConfigBase(jsonObj), _active(false)
{
    setActive(jsonObj);
}

void Profile::setActive(const json& jsonObj)
{
    if (!jsonObj.contains("method") || !jsonObj["method"].contains("name"))
    {
        // Log error on missing profile method
        log<level::ERR>("Missing required profile method",
                        entry("JSON=%s", jsonObj.dump().c_str()));
        throw std::runtime_error("Missing required profile method");
    }
    // The method to use in determining if the profile is active
    auto method = jsonObj["method"]["name"].get<std::string>();
    std::transform(method.begin(), method.end(), method.begin(), tolower);
    auto handler = _methods.find(method);
    if (handler != _methods.end())
    {
        // Call method for determining profile's active state
        _active = handler->second(jsonObj["method"]);
    }
    else
    {
        // Construct list of available methods
        auto methods = std::accumulate(std::next(_methods.begin()),
                                       _methods.end(), _methods.begin()->first,
                                       [](auto list, auto method) {
            return std::move(list) + ", " + method.first;
        });
        log<level::ERR>("Configured method not available",
                        entry("JSON=%s", jsonObj["method"].dump().c_str()),
                        entry("METHODS_AVAILABLE=%s", methods.c_str()));
    }
}

bool Profile::allOf(const json& method)
{
    if (!method.contains("properties"))
    {
        log<level::ERR>("Missing required all_of method properties list",
                        entry("JSON=%s", method.dump().c_str()));
        throw std::runtime_error(
            "Missing required all_of method properties list");
    }

    return std::all_of(method["properties"].begin(), method["properties"].end(),
                       [](const json& obj) {
        if (!obj.contains("path") || !obj.contains("interface") ||
            !obj.contains("property") || !obj.contains("value"))
        {
            log<level::ERR>(
                "Missing required all_of method property parameters",
                entry("JSON=%s", obj.dump().c_str()));
            throw std::runtime_error(
                "Missing required all_of method parameters");
        }
        auto variant = util::SDBusPlus::getPropertyVariant<PropertyVariantType>(
            obj["path"].get<std::string>(), obj["interface"].get<std::string>(),
            obj["property"].get<std::string>());

        return getJsonValue(obj["value"]) == variant;
    });
}

} // namespace phosphor::fan::control::json
