/**
 * Copyright © 2017 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 <phosphor-logging/log.hpp>
#include <string>
#include <tuple>
#include <vector>
#include "tach.hpp"
#include "rpolicy.hpp"

namespace phosphor
{
namespace fan
{
namespace presence
{

using namespace phosphor::logging;
using namespace std::literals::string_literals;

static const auto tachNamespace = "/xyz/openbmc_project/sensors/fan_tach/"s;
static const auto tachIface = "xyz.openbmc_project.Sensor.Value"s;
static const auto tachProperty = "Value"s;

Tach::Tach(
        const std::vector<std::string>& sensors) : currentState(false)
{
    // Initialize state.
    for (const auto& s : sensors)
    {
        state.emplace_back(s, nullptr, 0);
    }
}

bool Tach::start()
{
    for (size_t i = 0; i < state.size(); ++i)
    {
        auto& s = state[i];
        auto tachPath = tachNamespace + std::get<std::string>(s);

        // Register for signal callbacks.
        std::get<1>(s) = std::make_unique<sdbusplus::bus::match::match>(
                util::SDBusPlus::getBus(),
                sdbusplus::bus::match::rules::propertiesChanged(
                    tachPath, tachIface),
                [this, i](auto& msg){ this->propertiesChanged(i, msg);});

        // Get an initial tach speed.
        try
        {
            std::get<int64_t>(s) = util::SDBusPlus::getProperty<int64_t>(
                    tachPath,
                    tachIface,
                    tachProperty);
        }
        catch (std::exception&)
        {
            // Assume not spinning.

            std::get<int64_t>(s) = 0;
            log<level::INFO>(
                    "Unable to read fan tach sensor.",
                    entry("SENSOR=%s", tachPath));

        }
    }

    // Set the initial state of the sensor.
    currentState = std::any_of(
            state.begin(),
            state.end(),
            [](const auto & s)
            {
                return std::get<int64_t>(s) != 0;
            });

    return currentState;
}

void Tach::stop()
{
    for (auto& s : state)
    {
        // De-register signal callbacks.
        std::get<1>(s) = nullptr;
    }
}

bool Tach::present()
{
    // Live query the tach readings.
    std::vector<int64_t> values;
    for (const auto& s : state)
    {
        values.push_back(
                util::SDBusPlus::getProperty<int64_t>(
                        tachNamespace + std::get<std::string>(s),
                        tachIface,
                        tachProperty));
    }

    return std::any_of(
            values.begin(),
            values.end(),
            [](const auto & v) {return v != 0;});
}

void Tach::propertiesChanged(
        size_t sensor,
        sdbusplus::message::message& msg)
{
    std::string iface;
    util::Properties<int64_t> properties;
    msg.read(iface, properties);

    propertiesChanged(sensor, properties);
}

void Tach::propertiesChanged(
        size_t sensor,
        const util::Properties<int64_t>& props)
{
    auto& s = state[sensor];

    // Find the Value property containing the speed.
    auto it = props.find(tachProperty);
    if (it != props.end())
    {
        std::get<int64_t>(s) =
            sdbusplus::message::variant_ns::get<int64_t>(it->second);

        auto newState = std::any_of(
                state.begin(),
                state.end(),
                [](const auto & s)
                {
                    return std::get<int64_t>(s) != 0;
                });

        if (currentState != newState)
        {
            getPolicy().stateChanged(newState, *this);
            currentState = newState;
        }
    }
}

} // namespace presence
} // namespace fan
} // namespace phosphor
