#pragma once

#include <functional>
#include <optional>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
#include <sdeventplus/event.hpp>
#include <sdeventplus/utility/timer.hpp>
#include <string_view>
#include <unordered_map>
#include <utility>
#include <xyz/openbmc_project/State/Watchdog/server.hpp>

namespace phosphor
{
namespace watchdog
{

constexpr auto DEFAULT_MIN_INTERVAL_MS = 0;
namespace Base = sdbusplus::xyz::openbmc_project::State::server;
using WatchdogInherits = sdbusplus::server::object_t<Base::Watchdog>;

/** @class Watchdog
 *  @brief OpenBMC watchdog implementation.
 *  @details A concrete implementation for the
 *  xyz.openbmc_project.State.Watchdog DBus API.
 */
class Watchdog : public WatchdogInherits
{
  public:
    Watchdog() = delete;
    ~Watchdog() = default;
    Watchdog(const Watchdog&) = delete;
    Watchdog& operator=(const Watchdog&) = delete;
    Watchdog(Watchdog&&) = delete;
    Watchdog& operator=(Watchdog&&) = delete;

    /** @brief Type used to hold the name of a systemd target.
     */
    using TargetName = std::string;

    /** @brief Type used to store the mapping of a Watchdog timeout
     *         action to a systemd target.
     */
    using ActionTargetMap = std::unordered_map<Action, TargetName>;

    /** @brief Type used to specify the parameters of a fallback watchdog
     */
    struct Fallback
    {
        Action action;
        uint64_t interval;
        bool always;
    };

    /** @brief Constructs the Watchdog object
     *
     *  @param[in] bus              - DBus bus to attach to.
     *  @param[in] objPath          - Object path to attach to.
     *  @param[in] event            - reference to sdeventplus::Event loop
     *  @param[in] actionTargets    - map of systemd targets called on timeout
     *  @param[in] fallback         - fallback watchdog
     *  @param[in] minInterval      - minimum intervale value allowed
     *  @param[in] defaultInterval  - default interval to start with
     *  @param[in] exitAfterTimeout - should the event loop be terminated
     */
    Watchdog(sdbusplus::bus_t& bus, const char* objPath,
             const sdeventplus::Event& event,
             ActionTargetMap&& actionTargetMap = {},
             std::optional<Fallback>&& fallback = std::nullopt,
             uint64_t minInterval = DEFAULT_MIN_INTERVAL_MS,
             uint64_t defaultInterval = 0, bool exitAfterTimeout = false) :
        WatchdogInherits(bus, objPath),
        bus(bus), actionTargetMap(std::move(actionTargetMap)),
        fallback(fallback), minInterval(minInterval),
        timer(event, std::bind(&Watchdog::timeOutHandler, this)),
        objPath(objPath), exitAfterTimeout(exitAfterTimeout)
    {
        // Use default if passed in otherwise just use default that comes
        // with object
        if (defaultInterval)
        {
            interval(defaultInterval);
        }
        else
        {
            interval(interval());
        }
        // We need to poke the enable mechanism to make sure that the timer
        // enters the fallback state if the fallback is always enabled.
        tryFallbackOrDisable();
    }

    /** @brief Resets the TimeRemaining to the configured Interval
     *         Optionally enables the watchdog.
     *
     *  @param[in] enableWatchdog - Should the call enable the watchdog
     */
    void resetTimeRemaining(bool enableWatchdog) override;

    /** @brief Since we are overriding the setter-enabled but not the
     *         getter-enabled, we need to have this using in order to
     *         allow passthrough usage of the getter-enabled.
     */
    using Base::Watchdog::enabled;

    /** @brief Enable or disable watchdog
     *         If a watchdog state is changed from disable to enable,
     *         the watchdog timer is set with the default expiration
     *         interval and it starts counting down.
     *         If a watchdog is already enabled, setting @value to true
     *         has no effect.
     *
     *  @param[in] value - 'true' to enable. 'false' to disable
     *
     *  @return : applied value if success, previous value otherwise
     */
    bool enabled(bool value) override;

    /** @brief Gets the remaining time before watchdog expires.
     *
     *  @return 0 if watchdog is expired.
     *          Remaining time in milliseconds otherwise.
     */
    uint64_t timeRemaining() const override;

    /** @brief Reset timer to expire after new timeout in milliseconds.
     *
     *  @param[in] value - the time in milliseconds after which
     *                     the watchdog will expire
     *
     *  @return: updated timeout value if watchdog is enabled.
     *           0 otherwise.
     */
    uint64_t timeRemaining(uint64_t value) override;

    /** @brief Get value of Interval
     *
     *
     *  @return: current interval
     *
     */
    using WatchdogInherits::interval;

    /** @brief Set value of Interval
     *
     *  @param[in] value - interval time to set
     *
     *  @return: interval that was set
     *
     */
    uint64_t interval(uint64_t value) override;

    /** @brief Tells if the referenced timer is expired or not */
    inline auto timerExpired() const
    {
        return timer.hasExpired();
    }

    /** @brief Tells if the timer is running or not */
    inline bool timerEnabled() const
    {
        return timer.isEnabled();
    }

  private:
    /** @brief sdbusplus handle */
    sdbusplus::bus_t& bus;

    /** @brief Map of systemd units to be started when the timer expires */
    ActionTargetMap actionTargetMap;

    /** @brief Fallback timer options */
    std::optional<Fallback> fallback;

    /** @brief Minimum watchdog interval value */
    uint64_t minInterval;

    /** @brief Contained timer object */
    sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;

    /** @brief Optional Callback handler on timer expirartion */
    void timeOutHandler();

    /** @brief Attempt to enter the fallback watchdog or disables it */
    void tryFallbackOrDisable();

    /** @brief Object path of the watchdog */
    std::string_view objPath;

    /** @brief Do we terminate after exit */
    bool exitAfterTimeout;
};

} // namespace watchdog
} // namespace phosphor
