#pragma once

#include "hwmonio.hpp"
#include "sensorset.hpp"
#include "types.hpp"

#include <gpioplus/handle.hpp>
#include <stdplus/handle/managed.hpp>

#include <cerrno>
#include <future>
#include <map>
#include <memory>
#include <optional>
#include <unordered_set>

namespace sensor
{

using TimedoutMap = std::map<SensorSet::key_type, std::future<int64_t>>;

struct valueAdjust
{
    double gain = 1.0;
    int offset = 0;
    std::unordered_set<int> rmRCs;
};

/** @brief Custom exception for async sensor reading timeout
 */
struct AsyncSensorReadTimeOut : public std::system_error
{
    AsyncSensorReadTimeOut() :
        system_error(std::error_code(ETIMEDOUT, std::system_category()),
                     "Async sensor read timed out")
    {}
};

/** @class Sensor
 *  @brief Sensor object based on a SensorSet container's key type
 *  @details Sensor object to create and modify an associated device's sensor
 *  attributes based on the key type of each sensor in the set provided by the
 *  device.
 */
class Sensor
{
  public:
    Sensor() = delete;
    Sensor(const Sensor&) = delete;
    Sensor(Sensor&&) = default;
    Sensor& operator=(const Sensor&) = delete;
    Sensor& operator=(Sensor&&) = default;
    ~Sensor() = default;

    /**
     * @brief Constructs Sensor object
     *
     * @param[in] sensor - A pair of sensor indentifiers
     * @param[in] ioAccess - Hwmon sysfs access
     * @param[in] devPath - Device sysfs path
     */
    explicit Sensor(const SensorSet::key_type& sensor,
                    const hwmonio::HwmonIOInterface* ioAccess,
                    const std::string& devPath);

    /**
     * @brief Adds any sensor removal return codes for the sensor
     * @details Add all return codes defined within a device's config file
     * for the entire device or for the specific sensor.
     *
     * @param[in] rcList - List of return codes found for the sensor
     */
    void addRemoveRCs(const std::string& rcList);

    /**
     * @brief Get the adjustments struct for the sensor
     *
     * @return - Sensor adjustment struct
     */
    inline const valueAdjust& getAdjusts() const
    {
        return _sensorAdjusts;
    }

    /**
     * @brief Adjusts a sensor value
     * @details Adjusts the value given by any gain and/or offset defined
     * for this sensor object and returns that adjusted value.
     *
     * @param[in] value - Value to be adjusted
     *
     * @return - Adjusted sensor value
     */
    SensorValueType adjustValue(SensorValueType value);

    /**
     * @brief Add value interface and value property for sensor
     * @details When a sensor has an associated input file, the Sensor.Value
     * interface is added along with setting the Value property to the
     * corresponding value found in the input file.
     *
     * @param[in] retryIO - Hwmon sysfs file retry constraints
     *                      (number of and delay between)
     * @param[in] info - Sensor object information
     *
     * @param[in] timedoutMap - Map to track timed out threads
     *
     * @return - Shared pointer to the value object
     */
    std::shared_ptr<ValueObject> addValue(const RetryIO& retryIO,
                                          ObjectInfo& info,
                                          TimedoutMap& timedoutMap);

    /**
     * @brief Add status interface and functional property for sensor
     * @details OperationalStatus interface is added and the Functional property
     * is set depending on whether a fault file exists and if it does it will
     * also depend on the content of the fault file. _hasFaultFile will also be
     * set to true if fault file exists.
     *
     * @param[in] info - Sensor object information
     *
     * @return - Shared pointer to the status object
     */
    std::shared_ptr<StatusObject> addStatus(ObjectInfo& info);

    /**
     * @brief Add Accuracy interface and accuracy property for sensor
     * @details Accuracy interface is the accuracy range (+/-) of the sensor
     * Value as a percentage, with a value between 0 and 100.
     *
     * @param[in] info     - Sensor object information
     * @param[in] accuracy - The accuracy value for sensor readings
     *
     * @return - Shared pointer to the accuracy object
     */
    std::shared_ptr<AccuracyObject> addAccuracy(ObjectInfo& info,
                                                double accuracy);

    /**
     * @brief Add Priority interface and priority property for sensors
     * @details The Priority interface defines priority levels for sensors.
     *
     * @param[in] info     - Sensor object information
     * @param[in] priority - The priority level for the sensor
     *
     * @return - Shared pointer to the priority object
     */

    std::shared_ptr<PriorityObject> addPriority(ObjectInfo& info,
                                                size_t priority);

    /**
     * @brief Get the scale from the sensor.
     *
     * @return - Scale value
     */
    inline int64_t getScale(void) const
    {
        return _scale;
    }

    /**
     * @brief Get the GPIO handle from the sensor.
     *
     * @return - Pointer to the GPIO handle interface, can be nullptr.
     */
    inline const gpioplus::HandleInterface* getGpio(void) const
    {
        return _handle.get();
    }

    /**
     * @brief Get whether the sensor has a fault file or not.
     *
     * @return - Boolean on whether the sensor has a fault file
     */
    inline bool hasFaultFile(void) const
    {
        return _hasFaultFile;
    }

  private:
    /** @brief Sensor object's identifiers */
    SensorSet::key_type _sensor;

    /** @brief Hwmon sysfs access. */
    const hwmonio::HwmonIOInterface* _ioAccess;

    /** @brief Physical device sysfs path. */
    const std::string& _devPath;

    /** @brief Structure for storing sensor adjustments */
    valueAdjust _sensorAdjusts;

    /** @brief Optional pointer to GPIO handle. */
    std::unique_ptr<gpioplus::HandleInterface> _handle;

    /** @brief sensor scale from configuration. */
    int64_t _scale;

    /** @brief Tracks whether the sensor has a fault file or not. */
    bool _hasFaultFile;
};

/**
 * @brief Locks the gpio represented by the handle
 *
 * @param[in] handle - The gpio handle to lock
 */
void gpioLock(const gpioplus::HandleInterface*&& handle);

/** @brief The type which is responsible for managing the lock */
using GpioLocker =
    stdplus::Managed<const gpioplus::HandleInterface*>::Handle<gpioLock>;

/**
 * @brief Unlocks the gpio and creates a lock object to ensure
 *        the gpio is locked again.
 *
 * @param[in] handle - The gpio handle to unlock and wrap
 */
std::optional<GpioLocker> gpioUnlock(const gpioplus::HandleInterface* handle);

/**
 * @brief Asynchronously read a sensor with timeout defined by
 *        ASYNC_READ_TIMEOUT environment variable
 *
 * @param[in] sensorSetKey - Sensor object's identifiers
 * @param[in] ioAccess - Hwmon sysfs access
 * @param[in] asyncTimeout - Async read timeout in milliseconds
 * @param[in] timedoutMap - Map to track timed out threads
 *
 * (Params needed for HwmonIO::read)
 * @param[in] type - The hwmon type (ex. temp).
 * @param[in] id - The hwmon id (ex. 1).
 * @param[in] sensor - The hwmon sensor (ex. input).
 * @param[in] retries - The number of times to retry.
 * @param[in] delay - The time to sleep between retry attempts.
 *
 * @return - SensorValueType read asynchronously, will throw if timed out
 */
SensorValueType asyncRead(const SensorSet::key_type& sensorSetKey,
                          const hwmonio::HwmonIOInterface* ioAccess,
                          std::chrono::milliseconds asyncTimeout,
                          TimedoutMap& timedoutMap, const std::string& type,
                          const std::string& id, const std::string& sensor,
                          const size_t retries,
                          const std::chrono::milliseconds delay);
} // namespace sensor
