/*
// 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 <ipmid/api.hpp>
#include <ipmid/utils.hpp>
#include <multinodecommands.hpp>
#include <oemcommands.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/message/types.hpp>

#include <string>

namespace ipmi
{
void registerMultiNodeFunctions() __attribute__((constructor));

std::optional<uint8_t> getMultiNodeInfo(std::string name)
{
    auto pdbus = getSdBus();
    try
    {
        std::string service = getService(*pdbus, multiNodeIntf,
                                         multiNodeObjPath);
        Value dbusValue = getDbusProperty(*pdbus, service, multiNodeObjPath,
                                          multiNodeIntf, name);
        return std::get<uint8_t>(dbusValue);
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "getMultiNodeInfo: can't get multi node info from dbus!",
            phosphor::logging::entry("ERR=%s", e.what()));
        return std::nullopt;
    }
}

std::optional<uint8_t> getMultiNodeRole()
{
    auto pdbus = getSdBus();
    try
    {
        std::string service = getService(*pdbus, multiNodeIntf,
                                         multiNodeObjPath);
        Value dbusValue = getDbusProperty(*pdbus, service, multiNodeObjPath,
                                          multiNodeIntf, "NodeRole");
        std::string valueStr = std::get<std::string>(dbusValue);
        uint8_t value;
        if (valueStr == "single")
            value = static_cast<uint8_t>(NodeRole::single);
        else if (valueStr == "master")
            value = static_cast<uint8_t>(NodeRole::controller);
        else if (valueStr == "slave")
            value = static_cast<uint8_t>(NodeRole::target);
        else if (valueStr == "arbitrating")
            value = static_cast<uint8_t>(NodeRole::arbitrating);
        else
        {
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "getMultiNodeRole: Invalid dbus value!",
                phosphor::logging::entry("VALUE=%s", valueStr.c_str()));
            return std::nullopt;
        }
        return value;
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "getMultiNodeRole: can't get multi node role from dbus!",
            phosphor::logging::entry("ERR=%s", e.what()));
        return std::nullopt;
    }
}

ipmi::RspType<uint8_t> ipmiGetMultiNodePresence()

{
    std::optional<uint8_t> nodeInfo = getMultiNodeInfo("NodePresence");
    if (!nodeInfo)
    {
        return ipmi::responseResponseError();
    }

    return ipmi::responseSuccess(*nodeInfo);
}

ipmi::RspType<uint8_t> ipmiGetMultiNodeId()
{
    std::optional<uint8_t> nodeInfo = getMultiNodeInfo("NodeId");
    if (!nodeInfo)
    {
        return ipmi::responseResponseError();
    }

    return ipmi::responseSuccess(*nodeInfo);
}

ipmi::RspType<uint8_t> ipmiGetMultiNodeRole()
{
    std::optional<uint8_t> nodeInfo = getMultiNodeRole();
    if (!nodeInfo)
    {
        return ipmi::responseResponseError();
    }

    return ipmi::responseSuccess(*nodeInfo);
}

void registerMultiNodeFunctions(void)
{
    phosphor::logging::log<phosphor::logging::level::INFO>(
        "Registering MultiNode commands");

    ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral,
                          ipmi::intel::general::cmdGetMultiNodePresence,
                          ipmi::Privilege::User, ipmiGetMultiNodePresence);

    ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral,
                          ipmi::intel::general::cmdGetMultiNodeId,
                          ipmi::Privilege::User, ipmiGetMultiNodeId);

    ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral,
                          ipmi::intel::general::cmdGetMultiNodeRole,
                          ipmi::Privilege::User, ipmiGetMultiNodeRole);
}

} // namespace ipmi
