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