#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 identifiers
     * @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
