/**
 * 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 "fallback.hpp"

#include "fan.hpp"
#include "psensor.hpp"

#include <fmt/format.h>

#include <phosphor-logging/log.hpp>

#include <algorithm>

namespace phosphor
{
namespace fan
{
namespace presence
{

void Fallback::stateChanged(bool present, PresenceSensor& /*sensor*/)
{
    if (!present)
    {
        // Starting with the first backup, find the first
        // sensor that reports the fan as present, if any.
        auto it = std::find_if(std::next(activeSensor), sensors.end(),
                               [](auto& s) { return s.get().present(); });

        if (it != sensors.end())
        {
            // A backup sensor disagrees with the active sensor.
            // Switch to the backup.
            activeSensor->get().stop();
            present = it->get().start();

            while (activeSensor != it)
            {
                // Callout the broken sensors.
                activeSensor->get().fail();
                ++activeSensor;
            }
            phosphor::logging::log<phosphor::logging::level::INFO>(
                fmt::format("Using backup presence sensor for fan {}",
                            std::get<1>(fan))
                    .c_str());
            activeSensor = it;
        }
    }

    setPresence(fan, present);

    if (eepromDevice)
    {
        if (present)
        {
            eepromDevice->bind();
        }
        else
        {
            eepromDevice->unbind();
        }
    }
}

void Fallback::monitor()
{
    // Find the first sensor that says the fan is present
    // and set it as the active sensor.
    activeSensor = std::find_if(sensors.begin(), sensors.end(),
                                [](auto& s) { return s.get().present(); });
    if (activeSensor == sensors.end())
    {
        // The first sensor is working or all sensors
        // agree the fan isn't present.  Use the first sensor.
        activeSensor = sensors.begin();
    }

    if (activeSensor != sensors.begin())
    {
        phosphor::logging::log<phosphor::logging::level::INFO>(
            fmt::format("Using backup presence sensor for fan {}",
                        std::get<1>(fan))
                .c_str());
    }

    // Callout the broken sensors.
    auto it = sensors.begin();
    while (it != activeSensor)
    {
        it->get().fail();
        ++it;
    }

    // Start the active sensor and set the initial state.
    setPresence(fan, activeSensor->get().start());
}

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