#include "actions.hpp"

namespace phosphor
{
namespace fan
{
namespace control
{
namespace action
{

using namespace phosphor::fan;

Action call_actions_based_on_timer(TimerConf&& tConf,
                                   std::vector<Action>&& actions)
{
    return [tConf = std::move(tConf), actions = std::move(actions)](
               control::Zone& zone, const Group& group) {
        try
        {
            auto it = zone.getTimerEvents().find(__func__);
            if (it != zone.getTimerEvents().end())
            {
                auto& timers = it->second;
                auto timerIter = zone.findTimer(group, actions, timers);
                if (timerIter == timers.end())
                {
                    // No timer exists yet for action, add timer
                    zone.addTimer(__func__, group, actions, tConf);
                }
                else if (timerIter != timers.end())
                {
                    // Remove any timer for this group
                    timers.erase(timerIter);
                    if (timers.empty())
                    {
                        zone.getTimerEvents().erase(it);
                    }
                }
            }
            else
            {
                // No timer exists yet for event, add timer
                zone.addTimer(__func__, group, actions, tConf);
            }
        }
        catch (const std::out_of_range& oore)
        {
            // Group not found, no timers set
        }
    };
}

void default_floor_on_missing_owner(Zone& zone, const Group& group)
{
    // Set/update the services of the group
    zone.setServices(&group);
    auto services = zone.getGroupServices(&group);
    auto defFloor =
        std::any_of(services.begin(), services.end(),
                    [](const auto& s) { return !std::get<hasOwnerPos>(s); });
    if (defFloor)
    {
        zone.setFloor(zone.getDefFloor());
    }
    // Update fan control floor change allowed
    zone.setFloorChangeAllow(&group, !defFloor);
}

Action set_speed_on_missing_owner(uint64_t speed)
{
    return [speed](control::Zone& zone, const Group& group) {
        // Set/update the services of the group
        zone.setServices(&group);
        auto services = zone.getGroupServices(&group);
        auto missingOwner =
            std::any_of(services.begin(), services.end(), [](const auto& s) {
                return !std::get<hasOwnerPos>(s);
            });
        if (missingOwner)
        {
            zone.setSpeed(speed);
        }
        // Update group's fan control active allowed based on action results
        zone.setActiveAllow(&group, !missingOwner);
    };
}

void set_request_speed_base_with_max(control::Zone& zone, const Group& group)
{
    int64_t base = 0;
    std::for_each(
        group.begin(), group.end(), [&zone, &base](const auto& entry) {
            try
            {
                auto value = zone.template getPropertyValue<int64_t>(
                    std::get<pathPos>(entry), std::get<intfPos>(entry),
                    std::get<propPos>(entry));
                base = std::max(base, value);
            }
            catch (const std::out_of_range& oore)
            {
                // Property value not found, base request speed unchanged
            }
        });
    // A request speed base of 0 defaults to the current target speed
    zone.setRequestSpeedBase(base);
}

} // namespace action
} // namespace control
} // namespace fan
} // namespace phosphor
