#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 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
