#pragma once
#include <chrono>
#include <vector>
#include <cassert>
#include <algorithm>
#include <sdbusplus/bus.hpp>
#include "fan.hpp"
#include "types.hpp"
#include "timer.hpp"

namespace phosphor
{
namespace fan
{
namespace control
{

/**
 * The mode fan control will run in:
 *   - init - only do the initialization steps
 *   - control - run normal control algorithms
 */
enum class Mode
{
    init,
    control
};

/**
 * @class Represents a fan control zone, which is a group of fans
 * that behave the same.
 */
class Zone
{
    public:

        Zone() = delete;
        Zone(const Zone&) = delete;
        Zone(Zone&&) = default;
        Zone& operator=(const Zone&) = delete;
        Zone& operator=(Zone&&) = delete;
        ~Zone() = default;

        /**
         * Constructor
         * Creates the appropriate fan objects based on
         * the zone definition data passed in.
         *
         * @param[in] mode - mode of fan control
         * @param[in] bus - the dbus object
         * @param[in] events - sd_event pointer
         * @param[in] def - the fan zone definition data
         */
        Zone(Mode mode,
             sdbusplus::bus::bus& bus,
             phosphor::fan::event::EventPtr& events,
             const ZoneDefinition& def);

        /**
         * Sets all fans in the zone to the speed
         * passed in when the zone is active
         *
         * @param[in] speed - the fan speed
         */
        void setSpeed(uint64_t speed);

        /**
         * Sets the zone to full speed regardless of zone's active state
         */
        void setFullSpeed();

        /**
         * @brief Sets the automatic fan control allowed active state
         *
         * @param[in] group - A group that affects the active state
         * @param[in] isActiveAllow - Active state according to group
         */
        void setActiveAllow(const Group* group, bool isActiveAllow);

        /**
         * @brief Sets the floor change allowed state
         *
         * @param[in] group - A group that affects floor changes
         * @param[in] isAllow - Allow state according to group
         */
        inline void setFloorChangeAllow(const Group* group, bool isAllow)
        {
            _floorChange[*(group)] = isAllow;
        }

        /**
         * @brief Sets a given object's property value
         *
         * @param[in] object - Name of the object containing the property
         * @param[in] interface - Interface name containing the property
         * @param[in] property - Property name
         * @param[in] value - Property value
         */
        template <typename T>
        void setPropertyValue(const char* object,
                              const char* interface,
                              const char* property,
                              T value)
        {
            _properties[object][interface][property] = value;
        };

        /**
         * @brief Get the value of an object's property
         *
         * @param[in] object - Name of the object containing the property
         * @param[in] interface - Interface name containing the property
         * @param[in] property - Property name
         *
         * @return - The property value
         */
        template <typename T>
        inline auto getPropertyValue(const std::string& object,
                                     const std::string& interface,
                                     const std::string& property)
        {
            return sdbusplus::message::variant_ns::get<T>(
                    _properties.at(object).at(interface).at(property));
        };

        /**
         * @brief Get the object's property variant
         *
         * @param[in] object - Name of the object containing the property
         * @param[in] interface - Interface name containing the property
         * @param[in] property - Property name
         *
         * @return - The property variant
         */
        inline auto getPropValueVariant(const std::string& object,
                                        const std::string& interface,
                                        const std::string& property)
        {
            return _properties.at(object).at(interface).at(property);
        };

        /**
         * @brief Remove a service associated to a group
         *
         * @param[in] group - Group associated with service
         * @param[in] name - Service name to remove
         */
        void removeService(const Group* group,
                           const std::string& name);

        /**
         * @brief Set or update a service name owner in use
         *
         * @param[in] group - Group associated with service
         * @param[in] name - Service name
         * @param[in] hasOwner - Whether the service is owned or not
         */
        void setServiceOwner(const Group* group,
                             const std::string& name,
                             const bool hasOwner);

        /**
         * @brief Set or update all services for a group
         *
         * @param[in] group - Group to get service names for
         */
        void setServices(const Group* group);

        /**
         * @brief Get the group's list of service names
         *
         * @param[in] group - Group to get service names for
         *
         * @return - The list of service names
         */
        inline auto getGroupServices(const Group* group)
        {
            return _services.at(*group);
        }

        /**
         * @brief Initialize a set speed event properties and actions
         *
         * @param[in] event - Set speed event
         */
        void initEvent(const SetSpeedEvent& event);

        /**
         * @brief Removes all the set speed event properties and actions
         *
         * @param[in] event - Set speed event
         */
        void removeEvent(const SetSpeedEvent& event);

        /**
         * @brief Get the default floor speed
         *
         * @return - The defined default floor speed
         */
        inline auto getDefFloor()
        {
            return _defFloorSpeed;
        };

        /**
         * @brief Get the ceiling speed
         *
         * @return - The current ceiling speed
         */
        inline auto& getCeiling() const
        {
            return _ceilingSpeed;
        };

        /**
         * @brief Set the ceiling speed to the given speed
         *
         * @param[in] speed - Speed to set the ceiling to
         */
        inline void setCeiling(uint64_t speed)
        {
            _ceilingSpeed = speed;
        };

        /**
         * @brief Swaps the ceiling key value with what's given and
         * returns the value that was swapped.
         *
         * @param[in] keyValue - New ceiling key value
         *
         * @return - Ceiling key value prior to swapping
         */
        inline auto swapCeilingKeyValue(int64_t keyValue)
        {
            std::swap(_ceilingKeyValue, keyValue);
            return keyValue;
        };

        /**
         * @brief Get the increase speed delta
         *
         * @return - The current increase speed delta
         */
        inline auto& getIncSpeedDelta() const
        {
            return _incSpeedDelta;
        };

        /**
         * @brief Get the decrease speed delta
         *
         * @return - The current decrease speed delta
         */
        inline auto& getDecSpeedDelta() const
        {
            return _decSpeedDelta;
        };

        /**
         * @brief Set the floor speed to the given speed and increase target
         * speed to the floor when target is below floor where floor changes
         * are allowed.
         *
         * @param[in] speed - Speed to set the floor to
         */
        void setFloor(uint64_t speed);

        /**
         * @brief Set the requested speed base to be used as the speed to
         * base a new requested speed target from
         *
         * @param[in] speedBase - Base speed value to use
         */
        inline void setRequestSpeedBase(uint64_t speedBase)
        {
            _requestSpeedBase = speedBase;
        };

        /**
         * @brief Calculate the requested target speed from the given delta
         * and increase the fan speeds, not going above the ceiling.
         *
         * @param[in] targetDelta - The delta to increase the target speed by
         */
        void requestSpeedIncrease(uint64_t targetDelta);

        /**
         * @brief Calculate the requested target speed from the given delta
         * and increase the fan speeds, not going above the ceiling.
         *
         * @param[in] targetDelta - The delta to increase the target speed by
         */
        void requestSpeedDecrease(uint64_t targetDelta);

        /**
         * @brief Callback function for the increase timer that delays
         * processing of requested speed increases while fans are increasing
         */
        void incTimerExpired();

        /**
         * @brief Callback function for the decrease timer that processes any
         * requested speed decreases if allowed
         */
        void decTimerExpired();

        /**
         * @brief Get the event pointer used with this zone's timers
         *
         * @return - The Dbus event pointer for timers
         */
        inline auto& getEventPtr()
        {
            return _sdEvents;
        }

        /**
         * @brief Get the list of timer events
         *
         * @return - List of timer events
         */
        inline auto& getTimerEvents()
        {
            return _timerEvents;
        }

        /**
         * @brief Find the first instance of a timer event
         *
         * @param[in] eventGroup - Group associated with a timer
         * @param[in] eventActions - List of actions associated with a timer
         *
         * @return - Iterator to the timer event
         */
        std::vector<TimerEvent>::iterator findTimer(
                const Group& eventGroup,
                const std::vector<Action>& eventActions);

        /**
         * @brief Add a timer to the list of timer based events
         *
         * @param[in] data - Event data for timer
         * @param[in] timer - Timer to be added
         */
        inline void addTimer(
                std::unique_ptr<EventData>&& data,
                std::unique_ptr<phosphor::fan::util::Timer>&& timer)
        {
            _timerEvents.emplace_back(std::move(data), std::move(timer));
        };

        /**
         * @brief Remove the given timer event
         *
         * @param[in] teIter - Iterator pointing to the timer event to remove
         */
        inline void removeTimer(std::vector<TimerEvent>::iterator& teIter)
        {
            assert(teIter != std::end(_timerEvents));
            std::get<timerEventDataPos>(*teIter).reset();
            std::get<timerTimerPos>(*teIter).reset();
            _timerEvents.erase(teIter);
        }

        /**
         * @brief Callback function for event timers that processes the given
         * actions for a group
         *
         * @param[in] eventGroup - Group to process actions on
         * @param[in] eventActions - List of event actions to run
         */
        void timerExpired(Group eventGroup, std::vector<Action> eventActions);

    private:

        /**
         * The dbus object
         */
        sdbusplus::bus::bus& _bus;

        /**
         * Full speed for the zone
         */
        const uint64_t _fullSpeed;

        /**
         * The zone number
         */
        const size_t _zoneNum;

        /**
         * The default floor speed for the zone
         */
        const uint64_t _defFloorSpeed;

        /**
         * The default ceiling speed for the zone
         */
        const uint64_t _defCeilingSpeed;

        /**
         * The floor speed to not go below
         */
        uint64_t _floorSpeed = _defFloorSpeed;

        /**
         * The ceiling speed to not go above
         */
        uint64_t _ceilingSpeed = _defCeilingSpeed;

        /**
         * The previous sensor value for calculating the ceiling
         */
        int64_t _ceilingKeyValue = 0;

        /**
         * Automatic fan control active state
         */
        bool _isActive = true;

        /**
         * Target speed for this zone
         */
        uint64_t _targetSpeed = _fullSpeed;

        /**
         * Speed increase delta
         */
        uint64_t _incSpeedDelta = 0;

        /**
         * Speed decrease delta
         */
        uint64_t _decSpeedDelta = 0;

        /**
         * Requested speed base
         */
        uint64_t _requestSpeedBase = 0;

        /**
         * Speed increase delay in seconds
         */
        std::chrono::seconds _incDelay;

        /**
         * Speed decrease interval in seconds
         */
        std::chrono::seconds _decInterval;

        /**
         * The increase timer object
         */
        phosphor::fan::util::Timer _incTimer;

        /**
         * The decrease timer object
         */
        phosphor::fan::util::Timer _decTimer;

        /**
         * Dbus event used on set speed event timers
         */
        phosphor::fan::event::EventPtr& _sdEvents;

        /**
         * The vector of fans in this zone
         */
        std::vector<std::unique_ptr<Fan>> _fans;

        /**
         * @brief Map of object property values
         */
        std::map<std::string,
                 std::map<std::string,
                          std::map<std::string,
                                   PropertyVariantType>>> _properties;

        /**
         * @brief Map of active fan control allowed by groups
         */
        std::map<const Group, bool> _active;

        /**
         * @brief Map of floor change allowed by groups
         */
        std::map<const Group, bool> _floorChange;

        /**
         * @brief Map of group service names
         */
        std::map<const Group, std::vector<Service>> _services;

        /**
         * @brief List of signal event arguments and Dbus matches for callbacks
         */
        std::vector<SignalEvent> _signalEvents;

        /**
         * @brief List of timers for events
         */
        std::vector<TimerEvent> _timerEvents;

        /**
         * @brief Get the request speed base if defined, otherwise the
         * the current target speed is returned
         *
         * @return - The request speed base or current target speed
         */
        inline auto getRequestSpeedBase() const
        {
            return (_requestSpeedBase != 0) ? _requestSpeedBase : _targetSpeed;
        };

        /**
         * @brief Dbus signal change callback handler
         *
         * @param[in] msg - Expanded sdbusplus message data
         * @param[in] eventData - The single event's data
         */
        void handleEvent(sdbusplus::message::message& msg,
                         const EventData* eventData);
};

}
}
}
