#pragma once

#include "config.h"

#include "utils.hpp"

#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
#include <xyz/openbmc_project/Control/Power/CapLimits/server.hpp>

#include <filesystem>
#include <regex>

namespace open_power
{
namespace occ
{
class Status;

namespace powercap
{

namespace sdbusRule = sdbusplus::bus::match::rules;
namespace fs = std::filesystem;

constexpr auto PCAPLIMITS_PATH =
    "/xyz/openbmc_project/control/host0/power_cap_limits";

namespace Base = sdbusplus::xyz::openbmc_project::Control::Power::server;
using CapLimitsInterface = sdbusplus::server::object_t<Base::CapLimits>;

constexpr auto PCAPDATA_FILE_VERSION = 1;
struct PowerCapData
{
    uint32_t version = PCAPDATA_FILE_VERSION;
    bool initialized = false;
    uint32_t softMin = 0x0000;
    uint32_t hardMin = 0x0000;
    uint32_t max = UINT_MAX;
};

/** @class OccPersistCapData
 *  @brief Provides persistent container to store data for OCC
 *
 * Data is stored in filesystem
 */
class OccPersistCapData
{
  public:
    ~OccPersistCapData() = default;
    OccPersistCapData(const OccPersistCapData&) = default;
    OccPersistCapData& operator=(const OccPersistCapData&) = default;
    OccPersistCapData(OccPersistCapData&&) = default;
    OccPersistCapData& operator=(OccPersistCapData&&) = default;

    /** @brief Loads any saved power cap data */
    OccPersistCapData()
    {
        load();
    }

    /** @brief Save Power Mode data to persistent file
     *
     *  @param[in] softMin - soft minimum power cap in Watts
     *  @param[in] hardMin - hard minimum power cap in Watts
     *  @param[in] max     - maximum power cap in Watts
     */
    void updateCapLimits(const uint32_t softMin, const uint32_t hardMin,
                         const uint32_t max)
    {
        capData.softMin = softMin;
        capData.hardMin = hardMin;
        capData.max = max;
        capData.initialized = true;
        save();
    }

    /** @brief Return the power cap limits
     *
     *  @param[out] softMin - soft minimum power cap in Watts
     *  @param[out] hardMin - hard minimum power cap in Watts
     *  @param[out] max     - maximum power cap in Watts
     */
    void getCapLimits(uint32_t& softMin, uint32_t& hardMin, uint32_t& max) const
    {
        // If not initialized yet, still return PowerCapData defaults
        softMin = capData.softMin;
        hardMin = capData.hardMin;
        max = capData.max;
    }

    /** @brief Return true if the power cap limits are available */
    bool limitsAvailable()
    {
        return (capData.initialized);
    }

    /** @brief Saves the Power Mode data in the filesystem. */
    void save();

    /** @brief Trace the Power Mode and IPS parameters. */
    void print();

  private:
    /** @brief Power Mode data filename to store persistent data */
    static constexpr auto powerCapFilename = "powerCapData";

    /** @brief Power Mode data object to be persisted */
    PowerCapData capData;

    /** @brief Loads the persisted power cap data from the filesystem. */
    void load();
};

/** @class PowerCap
 *  @brief Monitors for changes to the power cap and notifies occ
 *
 *  The customer power cap is provided to the OCC by host TMGT when the occ
 *  first goes active or is reset.  This code is responsible for sending
 *  the power cap to the OCC if the cap is changed while the occ is active.
 */

class PowerCap : public CapLimitsInterface
{
  public:
    /** @brief PowerCap object to inform occ of changes to cap
     *
     * This object will monitor for changes to the power cap setting and
     * power cap enable properties.  If a change is detected, and the occ
     * is active, then this object will notify the OCC of the change.
     *
     * @param[in] occStatus - The occ status object
     */
    explicit PowerCap(Status& occStatus) :
        CapLimitsInterface(utils::getBus(), PCAPLIMITS_PATH,
                           CapLimitsInterface::action::defer_emit),
        occStatus(occStatus),
        pcapMatch(
            utils::getBus(),
            sdbusRule::member("PropertiesChanged") +
                sdbusRule::path(
                    "/xyz/openbmc_project/control/host0/power_cap") +
                sdbusRule::argN(0, "xyz.openbmc_project.Control.Power.Cap") +
                sdbusRule::interface("org.freedesktop.DBus.Properties"),
            std::bind(std::mem_fn(&PowerCap::pcapChanged), this,
                      std::placeholders::_1))
    {
        //  Read the current limits from persistent data
        uint32_t capSoftMin, capHardMin, capMax;
        persistedData.getCapLimits(capSoftMin, capHardMin, capMax);
        // Update limits on dbus
        updateDbusPcapLimits(capSoftMin, capHardMin, capMax);
        // CapLimit interface is now ready
        this->emit_object_added();
    };

    /** @brief Return the appropriate value to write to the OCC (output/DC
     * power)
     *
     * @param[in]  pcap        - Current user power cap setting (input/AC power)
     * @param[in]  pcapEnabled - Current power cap enable setting
     *
     * @return The value to write to the occ user pcap
     */
    uint32_t getOccInput(uint32_t pcap, bool pcapEnabled);

    /** @brief Read the power cap bounds from sysfs and update DBus */
    void updatePcapBounds();

  private:
    /** @brief Persisted power cap limits */
    OccPersistCapData persistedData;

    /** @brief Callback for pcap setting changes
     *
     * Process change and inform OCC
     *
     * @param[in]  msg       - Data associated with pcap change signal
     *
     */
    void pcapChanged(sdbusplus::message_t& msg);

    /** @brief Get the power cap property
     *
     * @return Power cap, 0 on failure to indicate no pcap
     */
    uint32_t getPcap();

    /** @brief Get the power cap enable property
     *
     * @return Whether power cap enabled, will return false on error
     */
    bool getPcapEnabled();

    /** @brief Write the output/DC power cap to the occ hwmon entry
     *
     * @param[in]  pcapValue - Power cap value to write to OCC
     */
    void writeOcc(uint32_t pcapValue);

    /** @brief Read the user power cap from sysfs
     *
     * @return User power cap value in Watts or 0 if disabled
     */
    uint32_t readUserCapHwmon();

    /**
     * @brief Returns the filename to use for the user power cap
     *
     * The file is of the form "powerX_cap_user", where X is any
     * number.
     *
     * @param[in] expr - Regular expression of file to find
     *
     * @return full path/filename, or empty path if not found.
     */
    fs::path getPcapFilename(const std::regex& expr);

    /* @brief OCC Status object */
    Status& occStatus;

    /** @brief Used to subscribe to dbus pcap property changes **/
    sdbusplus::bus::match_t pcapMatch;

    /** @brief Path to the sysfs files holding the cap properties **/
    fs::path pcapBasePathname;

    /** @brief Update the power cap bounds on DBus
     *
     * @param[in]  softMin - soft minimum power cap in Watts
     * @param[in]  hardMin - hard minimum power cap in Watts
     * @param[in]  pcapMax - maximum power cap in Watts
     */
    void updateDbusPcapLimits(uint32_t softMin, uint32_t hardMin,
                              uint32_t pcapMax);
};

} // namespace powercap

} // namespace occ

} // namespace open_power
