#include "config.h"

#include "sensor.hpp"

#include "env.hpp"
#include "gpio_handle.hpp"
#include "hwmon.hpp"
#include "sensorset.hpp"
#include "sysfs.hpp"

#include <fmt/format.h>

#include <phosphor-logging/elog-errors.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/Sensor/Device/error.hpp>

#include <cassert>
#include <chrono>
#include <cmath>
#include <cstring>
#include <filesystem>
#include <future>
#include <thread>

namespace sensor
{

using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;

// todo: this can be simplified once we move to the double interface
Sensor::Sensor(const SensorSet::key_type& sensor,
               const hwmonio::HwmonIOInterface* ioAccess,
               const std::string& devPath) :
    _sensor(sensor),
    _ioAccess(ioAccess), _devPath(devPath), _scale(0), _hasFaultFile(false)
{
    auto chip = env::getEnv("GPIOCHIP", sensor);
    auto access = env::getEnv("GPIO", sensor);
    if (!access.empty() && !chip.empty())
    {
        _handle = gpio::BuildGpioHandle(chip, access);

        if (!_handle)
        {
            log<level::ERR>("Unable to set up gpio locking");
            elog<InternalFailure>();
        }
    }

    auto gain = env::getEnv("GAIN", sensor);
    if (!gain.empty())
    {
        _sensorAdjusts.gain = std::stod(gain);
    }

    auto offset = env::getEnv("OFFSET", sensor);
    if (!offset.empty())
    {
        _sensorAdjusts.offset = std::stoi(offset);
    }
    auto senRmRCs = env::getEnv("REMOVERCS", sensor);
    // Add sensor removal return codes defined per sensor
    addRemoveRCs(senRmRCs);
}

void Sensor::addRemoveRCs(const std::string& rcList)
{
    if (rcList.empty())
    {
        return;
    }

    // Convert to a char* for strtok
    std::vector<char> rmRCs(rcList.c_str(), rcList.c_str() + rcList.size() + 1);
    auto rmRC = std::strtok(&rmRCs[0], ", ");
    while (rmRC != nullptr)
    {
        try
        {
            _sensorAdjusts.rmRCs.insert(std::stoi(rmRC));
        }
        catch (const std::logic_error& le)
        {
            // Unable to convert to int, continue to next token
            std::string name = _sensor.first + "_" + _sensor.second;
            log<level::INFO>("Unable to convert sensor removal return code",
                             entry("SENSOR=%s", name.c_str()),
                             entry("RC=%s", rmRC),
                             entry("EXCEPTION=%s", le.what()));
        }
        rmRC = std::strtok(nullptr, ", ");
    }
}

SensorValueType Sensor::adjustValue(SensorValueType value)
{
// Because read doesn't have an out pointer to store errors.
// let's assume negative values are errors if they have this
// set.
#if NEGATIVE_ERRNO_ON_FAIL
    if (value < 0)
    {
        return value;
    }
#endif

    // Adjust based on gain and offset
    value = static_cast<decltype(value)>(static_cast<double>(value) *
                                             _sensorAdjusts.gain +
                                         _sensorAdjusts.offset);

    if constexpr (std::is_same<SensorValueType, double>::value)
    {
        value *= std::pow(10, _scale);
    }

    return value;
}

std::shared_ptr<ValueObject> Sensor::addValue(const RetryIO& retryIO,
                                              ObjectInfo& info,
                                              TimedoutMap& timedoutMap)
{
    // Get the initial value for the value interface.
    auto& bus = *std::get<sdbusplus::bus_t*>(info);
    auto& obj = std::get<InterfaceMap>(info);
    auto& objPath = std::get<std::string>(info);

    SensorValueType val = 0;

    auto& statusIface = std::any_cast<std::shared_ptr<StatusObject>&>(
        obj[InterfaceType::STATUS]);
    // As long as addStatus is called before addValue, statusIface
    // should never be nullptr
    assert(statusIface);

    // Only read the input value if the status is functional
    if (statusIface->functional())
    {
#if UPDATE_FUNCTIONAL_ON_FAIL
        try
#endif
        {
            // RAII object for GPIO unlock / lock
            auto locker = gpioUnlock(getGpio());

            // For sensors with attribute ASYNC_READ_TIMEOUT,
            // spawn a thread with timeout
            auto asyncReadTimeout = env::getEnv("ASYNC_READ_TIMEOUT", _sensor);
            if (!asyncReadTimeout.empty())
            {
                std::chrono::milliseconds asyncTimeout{
                    std::stoi(asyncReadTimeout)};
                val = asyncRead(_sensor, _ioAccess, asyncTimeout, timedoutMap,
                                _sensor.first, _sensor.second,
                                hwmon::entry::cinput, std::get<size_t>(retryIO),
                                std::get<std::chrono::milliseconds>(retryIO));
            }
            else
            {
                // Retry for up to a second if device is busy
                // or has a transient error.
                val = _ioAccess->read(
                    _sensor.first, _sensor.second, hwmon::entry::cinput,
                    std::get<size_t>(retryIO),
                    std::get<std::chrono::milliseconds>(retryIO));
            }
        }
#if UPDATE_FUNCTIONAL_ON_FAIL
        catch (const std::system_error& e)
        {
            // Catch the exception here and update the functional property.
            // By catching the exception, it will not propagate it up the stack
            // and thus the code will skip the "Remove RCs" check in
            // MainLoop::getObject and will not exit on failure.
            statusIface->functional(false);
        }
#endif
    }

    auto iface = std::make_shared<ValueObject>(bus, objPath.c_str(),
                                               ValueObject::action::defer_emit);

    hwmon::Attributes attrs;
    if (hwmon::getAttributes(_sensor.first, attrs))
    {
        iface->unit(hwmon::getUnit(attrs));

        _scale = hwmon::getScale(attrs);
    }

    val = adjustValue(val);
    iface->value(val);

    auto maxValue = env::getEnv("MAXVALUE", _sensor);
    if (!maxValue.empty())
    {
        iface->maxValue(std::stoll(maxValue));
    }
    auto minValue = env::getEnv("MINVALUE", _sensor);
    if (!minValue.empty())
    {
        iface->minValue(std::stoll(minValue));
    }

    obj[InterfaceType::VALUE] = iface;
    return iface;
}

std::shared_ptr<StatusObject> Sensor::addStatus(ObjectInfo& info)
{
    namespace fs = std::filesystem;

    std::shared_ptr<StatusObject> iface = nullptr;
    auto& objPath = std::get<std::string>(info);
    auto& obj = std::get<InterfaceMap>(info);

    // Check if fault sysfs file exists
    std::string faultName = _sensor.first;
    std::string faultID = _sensor.second;
    std::string entry = hwmon::entry::fault;

    bool functional = true;
    auto sysfsFullPath = sysfs::make_sysfs_path(_ioAccess->path(), faultName,
                                                faultID, entry);
    if (fs::exists(sysfsFullPath))
    {
        _hasFaultFile = true;
        try
        {
            uint32_t fault = _ioAccess->read(faultName, faultID, entry,
                                             hwmonio::retries, hwmonio::delay);
            if (fault != 0)
            {
                functional = false;
            }
        }
        catch (const std::system_error& e)
        {
            using namespace sdbusplus::xyz::openbmc_project::Sensor::Device::
                Error;
            using metadata = xyz::openbmc_project::Sensor::Device::ReadFailure;

            report<ReadFailure>(
                metadata::CALLOUT_ERRNO(e.code().value()),
                metadata::CALLOUT_DEVICE_PATH(_devPath.c_str()));

            log<level::INFO>(fmt::format("Failing sysfs file: {} errno {}",
                                         sysfsFullPath, e.code().value())
                                 .c_str());
        }
    }

    auto& bus = *std::get<sdbusplus::bus_t*>(info);

    iface = std::make_shared<StatusObject>(
        bus, objPath.c_str(), StatusObject::action::emit_no_signals);
    // Set functional property
    iface->functional(functional);

    obj[InterfaceType::STATUS] = iface;

    return iface;
}

std::shared_ptr<AccuracyObject> Sensor::addAccuracy(ObjectInfo& info,
                                                    double accuracy)
{
    auto& objPath = std::get<std::string>(info);
    auto& obj = std::get<InterfaceMap>(info);

    auto& bus = *std::get<sdbusplus::bus_t*>(info);
    auto iface = std::make_shared<AccuracyObject>(
        bus, objPath.c_str(), AccuracyObject::action::emit_no_signals);

    iface->accuracy(accuracy);
    obj[InterfaceType::ACCURACY] = iface;

    return iface;
}

void gpioLock(const gpioplus::HandleInterface*&& handle)
{
    handle->setValues({0});
}

std::optional<GpioLocker> gpioUnlock(const gpioplus::HandleInterface* handle)
{
    if (handle == nullptr)
    {
        return std::nullopt;
    }

    handle->setValues({1});
    // Default pause needed to guarantee sensors are ready
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    return GpioLocker(std::move(handle));
}

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)
{
    // Default async read timeout
    bool valueIsValid = false;
    std::future<int64_t> asyncThread;

    auto asyncIter = timedoutMap.find(sensorSetKey);
    if (asyncIter == timedoutMap.end())
    {
        // If sensor not found in timedoutMap, spawn an async thread
        asyncThread = std::async(std::launch::async,
                                 &hwmonio::HwmonIOInterface::read, ioAccess,
                                 type, id, sensor, retries, delay);
        valueIsValid = true;
    }
    else
    {
        // If we already have the async thread in the timedoutMap, it means this
        // sensor has already timed out in the previous reads. No need to wait
        // on subsequent reads - proceed to check the future_status to see when
        // the async thread finishes
        asyncTimeout = std::chrono::seconds(0);
        asyncThread = std::move(asyncIter->second);
    }

    // TODO: This is still not a true asynchronous read as it still blocks the
    // main thread for asyncTimeout amount of time. To make this completely
    // asynchronous, schedule a read and register a callback to update the
    // sensor value
    std::future_status status = asyncThread.wait_for(asyncTimeout);
    switch (status)
    {
        case std::future_status::ready:
            // Read has finished
            if (valueIsValid)
            {
                return asyncThread.get();
                // Good sensor reads should skip the code below
            }
            // Async read thread has completed but had previously timed out (was
            // found in the timedoutMap). Erase from timedoutMap and throw to
            // allow retry in the next read cycle. Not returning the read value
            // as the sensor reading may be bad / corrupted if it took so long.
            timedoutMap.erase(sensorSetKey);
            throw AsyncSensorReadTimeOut();
        default:
            // Read timed out so add the thread to the timedoutMap (if the entry
            // already exists, operator[] updates it).
            //
            // Keeping the timed out futures in a map is required to prevent
            // their destructor from being called when returning from this
            // stack. The destructor will otherwise block until the read
            // completes due to the limitation of std::async.
            timedoutMap[sensorSetKey] = std::move(asyncThread);
            throw AsyncSensorReadTimeOut();
    }
}

} // namespace sensor
