#pragma once

#include "config.h"

#include "occ_errors.hpp"
#include "occ_events.hpp"
#include "occ_ffdc.hpp"
#include "occ_presence.hpp"

#include <org/open_power/OCC/Device/error.hpp>

#include <filesystem>
#include <fstream>

namespace open_power
{
namespace occ
{

class Manager;
class Status;
namespace fs = std::filesystem;
using namespace sdbusplus::org::open_power::OCC::Device::Error;

/** @class Device
 *  @brief Binds and unbinds the OCC driver upon request
 */
class Device
{
  public:
    Device() = delete;
    ~Device() = default;
    Device(const Device&) = delete;
    Device& operator=(const Device&) = delete;
    Device(Device&&) = default;
    Device& operator=(Device&&) = default;

    /** @brief Constructs the Device object
     *
     *  @param[in] event    - Unique ptr reference to sd_event
     *  @param[in] path     - Path to the OCC instance
     *  @param[in] manager  - OCC manager instance
     *  @param[in] status   - Status instance
     *  @param[in] instance - OCC instance number
     */
    Device(EventPtr& event, const fs::path& path, Manager& manager,
           Status& status, unsigned int instance = 0) :
        config(getPathBack(path)),
        devPath(path), instance(instance), statusObject(status),
        managerObject(manager),
        error(event, path / "occ_error",
              std::bind(std::mem_fn(&Device::errorCallback), this,
                        std::placeholders::_1)),
        timeout(event,
                path /
                    fs::path("../../sbefifo" + std::to_string(instance + 1)) /
                    "timeout",
#ifdef PLDM
                std::bind(std::mem_fn(&Device::timeoutCallback), this,
                          std::placeholders::_1)
#else
                nullptr
#endif
                    ),
        ffdc(event, path / "ffdc", instance),
        presence(event, path / "occs_present", manager,
                 std::bind(std::mem_fn(&Device::errorCallback), this,
                           std::placeholders::_1)),
        throttleProcTemp(
            event, path / "occ_dvfs_overtemp",
            std::bind(std::mem_fn(&Device::throttleProcTempCallback), this,
                      std::placeholders::_1)),
        throttleProcPower(
            event, path / "occ_dvfs_power",
            std::bind(std::mem_fn(&Device::throttleProcPowerCallback), this,
                      std::placeholders::_1)),
        throttleMemTemp(event, path / "occ_mem_throttle",
                        std::bind(std::mem_fn(&Device::throttleMemTempCallback),
                                  this, std::placeholders::_1))
    {
        // Nothing to do here
    }

    /** @brief Binds device to the OCC driver */
    inline void bind()
    {
        // Bind the device
        return write(bindPath, config);
    }

    /** @brief Un-binds device from the OCC driver */
    inline void unBind()
    {
        // Unbind the device
        return write(unBindPath, config);
    }

    /** @brief Returns if device is already bound.
     *
     *  On device bind, a soft link by the name $config
     *  gets created in OCC_HWMON_PATH and gets removed
     *  on unbind
     *
     *  @return true if bound, else false
     */
    inline bool bound() const
    {
        return fs::exists(OCC_HWMON_PATH + config);
    }

    /** @brief Starts to monitor for errors
     *
     *  @param[in] poll - Indicates whether or not the error file should
     *                    actually be polled for changes. Disabling polling is
     *                    necessary for error files that don't support the poll
     *                    file operation.
     */
    inline void addErrorWatch(bool poll = true)
    {
        try
        {
            throttleProcTemp.addWatch(poll);
        }
        catch (const OpenFailure& e)
        {
            // try the old kernel version
            throttleProcTemp.setFile(devPath / "occ_dvfs_ot");
            throttleProcTemp.addWatch(poll);
        }

        throttleProcPower.addWatch(poll);
        throttleMemTemp.addWatch(poll);

        try
        {
            ffdc.addWatch(poll);
        }
        catch (const OpenFailure& e)
        {
            // nothing to do if there is no FFDC file
        }

        try
        {
            timeout.addWatch(poll);
        }
        catch (const std::exception& e)
        {
            // nothing to do if there is no SBE timeout file
        }

        error.addWatch(poll);
    }

    /** @brief stops monitoring for errors */
    inline void removeErrorWatch()
    {
        // we can always safely remove watch even if we don't add it
        presence.removeWatch();
        ffdc.removeWatch();
        error.removeWatch();
        timeout.removeWatch();
        throttleMemTemp.removeWatch();
        throttleProcPower.removeWatch();
        throttleProcTemp.removeWatch();
    }

    /** @brief Starts to watch how many OCCs are present on the master */
    inline void addPresenceWatchMaster()
    {
        if (master())
        {
            presence.addWatch();
        }
    }

    /** @brief helper function to get the last part of the path
     *
     * @param[in] path - Path to parse
     * @return         - Last directory name in the path
     */
    static std::string getPathBack(const fs::path& path);

    /** @brief Returns true if device represents the master OCC */
    bool master() const;

  private:
    /** @brief Config value to be used to do bind and unbind */
    const std::string config;

    /** @brief This directory contains the error files */
    const fs::path devPath;

    /** @brief OCC instance ID */
    const unsigned int instance;

    /**  @brief To bind the device to the OCC driver, do:
     *
     *    Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/bind
     */
    static fs::path bindPath;

    /**  @brief To un-bind the device from the OCC driver, do:
     *    Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/unbind
     */
    static fs::path unBindPath;

    /**  Store the associated Status instance */
    Status& statusObject;

    /** Store the parent Manager instance */
    Manager& managerObject;

    /** Abstraction of error monitoring */
    Error error;

    /** Abstraction of SBE timeout monitoring */
    Error timeout;

    /** SBE FFDC monitoring */
    FFDC ffdc;

    /** Abstraction of OCC presence monitoring */
    Presence presence;

    /** Error instances for watching for throttling events */
    Error throttleProcTemp;
    Error throttleProcPower;
    Error throttleMemTemp;

    /** @brief file writer to achieve bind and unbind
     *
     *  @param[in] filename - Name of file to be written
     *  @param[in] data     - Data to be written to
     *  @return             - None
     */
    void write(const fs::path& fileName, const std::string& data)
    {
        // If there is an error, move the exception all the way up
        std::ofstream file(fileName, std::ios::out);
        file << data;
        file.close();
        return;
    }

    /** @brief callback for OCC error and presence monitoring
     *
     * @param[in] error - True if an error is reported, false otherwise
     */
    void errorCallback(bool error);

#ifdef PLDM
    /** @brief callback for SBE timeout monitoring
     *
     * @param[in] error - True if an error is reported, false otherwise
     */
    void timeoutCallback(bool error);
#endif

    /** @brief callback for the proc temp throttle event
     *
     *  @param[in] error - True if an error is reported, false otherwise
     */
    void throttleProcTempCallback(bool error);

    /** @brief callback for the proc power throttle event
     *
     *  @param[in] error - True if an error is reported, false otherwise
     */
    void throttleProcPowerCallback(bool error);

    /** @brief callback for the proc temp throttle event
     *
     *  @param[in] error - True if an error is reported, false otherwise
     */
    void throttleMemTempCallback(bool error);
};

} // namespace occ
} // namespace open_power
