#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
