/**
 * Copyright 2017 Google Inc.
 *
 * 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 "config.h"

#include "dbushelper.hpp"

#include "dbushelper_interface.hpp"
#include "dbusutil.hpp"

#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>

#include <map>
#include <string>
#include <variant>
#include <vector>

namespace pid_control
{

using Property = std::string;
using Value = std::variant<int64_t, double, std::string, bool>;
using PropertyMap = std::map<Property, Value>;

using namespace phosphor::logging;

/* TODO(venture): Basically all phosphor apps need this, maybe it should be a
 * part of sdbusplus.  There is an old version in libmapper.
 */
std::string DbusHelper::getService(const std::string& intf,
                                   const std::string& path)
{
    auto mapper = _bus.new_method_call("xyz.openbmc_project.ObjectMapper",
                                       "/xyz/openbmc_project/object_mapper",
                                       "xyz.openbmc_project.ObjectMapper",
                                       "GetObject");

    mapper.append(path);
    mapper.append(std::vector<std::string>({intf}));

    std::map<std::string, std::vector<std::string>> response;

    try
    {
        auto responseMsg = _bus.call(mapper);

        responseMsg.read(response);
    }
    catch (const sdbusplus::exception_t& ex)
    {
        log<level::ERR>("ObjectMapper call failure",
                        entry("WHAT=%s", ex.what()));
        throw;
    }

    if (response.begin() == response.end())
    {
        throw std::runtime_error("Unable to find Object: " + path);
    }

    return response.begin()->first;
}

void DbusHelper::getProperties(const std::string& service,
                               const std::string& path, SensorProperties* prop)
{
    auto pimMsg = _bus.new_method_call(service.c_str(), path.c_str(),
                                       propertiesintf, "GetAll");

    pimMsg.append(sensorintf);

    PropertyMap propMap;

    try
    {
        auto valueResponseMsg = _bus.call(pimMsg);
        valueResponseMsg.read(propMap);
    }
    catch (const sdbusplus::exception_t& ex)
    {
        log<level::ERR>("GetAll Properties Failed",
                        entry("WHAT=%s", ex.what()));
        throw;
    }

    // The PropertyMap returned will look like this because it's always
    // reading a Sensor.Value interface.
    // a{sv} 3:
    // "Value" x 24875
    // "Unit" s "xyz.openbmc_project.Sensor.Value.Unit.DegreesC"
    // "Scale" x -3

    // If no error was set, the values should all be there.
    auto findUnit = propMap.find("Unit");
    if (findUnit != propMap.end())
    {
        prop->unit = std::get<std::string>(findUnit->second);
    }
    auto findScale = propMap.find("Scale");
    auto findMax = propMap.find("MaxValue");
    auto findMin = propMap.find("MinValue");

    prop->min = 0;
    prop->max = 0;
    prop->scale = 0;
    if (findScale != propMap.end())
    {
        prop->scale = std::get<int64_t>(findScale->second);
    }
    if (findMax != propMap.end())
    {
        prop->max = std::visit(VariantToDoubleVisitor(), findMax->second);
    }
    if (findMin != propMap.end())
    {
        prop->min = std::visit(VariantToDoubleVisitor(), findMin->second);
    }

    prop->value = std::visit(VariantToDoubleVisitor(), propMap["Value"]);

    bool available = true;
    try
    {
        getProperty(service, path, availabilityIntf, "Available", available);
    }
    catch (const sdbusplus::exception_t& ex)
    {
        // unsupported Available property, leaving reading at 'True'
    }
    prop->available = available;

    return;
}

bool DbusHelper::thresholdsAsserted(const std::string& service,
                                    const std::string& path)
{
    auto critical = _bus.new_method_call(service.c_str(), path.c_str(),
                                         propertiesintf, "GetAll");
    critical.append(criticalThreshInf);
    PropertyMap criticalMap;

    try
    {
        auto msg = _bus.call(critical);
        msg.read(criticalMap);
    }
    catch (const sdbusplus::exception_t&)
    {
        // do nothing, sensors don't have to expose critical thresholds
#ifndef UNC_FAILSAFE
        return false;
#endif
    }

    auto findCriticalLow = criticalMap.find("CriticalAlarmLow");
    auto findCriticalHigh = criticalMap.find("CriticalAlarmHigh");

    bool asserted = false;
    if (findCriticalLow != criticalMap.end())
    {
        asserted = std::get<bool>(findCriticalLow->second);
    }

    // as we are catching properties changed, a sensor could theoretically jump
    // from one threshold to the other in one event, so check both thresholds
    if (!asserted && findCriticalHigh != criticalMap.end())
    {
        asserted = std::get<bool>(findCriticalHigh->second);
    }
#ifdef UNC_FAILSAFE
    if (!asserted)
    {
        auto warning = _bus.new_method_call(service.c_str(), path.c_str(),
                                            propertiesintf, "GetAll");
        warning.append(warningThreshInf);
        PropertyMap warningMap;

        try
        {
            auto msg = _bus.call(warning);
            msg.read(warningMap);
        }
        catch (const sdbusplus::exception_t&)
        {
            // sensors don't have to expose non-critical thresholds
            return false;
        }
        auto findWarningHigh = warningMap.find("WarningAlarmHigh");

        if (findWarningHigh != warningMap.end())
        {
            asserted = std::get<bool>(findWarningHigh->second);
        }
    }
#endif
    return asserted;
}

} // namespace pid_control
