/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "config.h"

#include "hwmonio.hpp"

#include "sysfs.hpp"

#include <algorithm>
#include <exception>
#include <fstream>
#include <thread>

namespace hwmonio
{

static constexpr auto retryableErrors = {
    /*
     * Retry on bus or device errors or timeouts in case
     * they are transient.
     */
    EIO,
    ETIMEDOUT,

    /*
     * Retry CRC errors.
     */
    EBADMSG,

    /*
     * Some hwmon drivers do this when they aren't ready
     * instead of blocking.  Retry.
     */
    EAGAIN,
    /*
     * We'll see this when for example i2c devices are
     * unplugged but the driver is still bound.  Retry
     * rather than exit on the off chance the device is
     * plugged back in and the driver doesn't do a
     * remove/probe.  If a remove does occur, we'll
     * eventually get ENOENT.
     */
    ENXIO,

    /*
     * Some devices return this when they are busy doing
     * something else.  Even if being busy isn't the cause,
     * a retry still gives this app a shot at getting data
     * as opposed to failing out on the first try.
     */
    ENODATA,

    /*
     * Some devices return this if the hardware is being
     * powered off in a normal manner, as incomplete data
     * is received. Retrying allows time for the system to
     * clean up driver devices, or in the event of a real
     * failure, attempt to get the rest of the data.
     */
    EMSGSIZE,
};

HwmonIO::HwmonIO(const std::string& path) : p(path)
{
}

int64_t HwmonIO::read(const std::string& type, const std::string& id,
                      const std::string& sensor, size_t retries,
                      std::chrono::milliseconds delay) const
{
    int64_t val;
    std::ifstream ifs;
    auto fullPath = sysfs::make_sysfs_path(p, type, id, sensor);

    ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit |
                   std::ifstream::eofbit);

    while (true)
    {
        try
        {
            errno = 0;
            if (!ifs.is_open())
                ifs.open(fullPath);
            ifs.clear();
            ifs.seekg(0);
            ifs >> val;
        }
        catch (const std::exception& e)
        {
            auto rc = errno;

            if (!rc)
            {
                throw;
            }

            if (rc == ENOENT || rc == ENODEV)
            {
                // If the directory or device disappeared then this application
                // should gracefully exit.  There are race conditions between
                // the unloading of a hwmon driver and the stopping of this
                // service by systemd.  To prevent this application from falsely
                // failing in these scenarios, it will simply exit if the
                // directory or file can not be found.  It is up to the user(s)
                // of this provided hwmon object to log the appropriate errors
                // if the object disappears when it should not.
                exit(0);
            }

            if (0 == std::count(retryableErrors.begin(), retryableErrors.end(),
                                rc) ||
                !retries)
            {
                // Not a retryable error or out of retries.
#ifdef NEGATIVE_ERRNO_ON_FAIL
                return -rc;
#endif

                // Work around GCC bugs 53984 and 66145 for callers by
                // explicitly raising system_error here.
                throw std::system_error(rc, std::generic_category());
            }

            --retries;
            std::this_thread::sleep_for(delay);
            continue;
        }
        break;
    }

    return val;
}

void HwmonIO::write(uint32_t val, const std::string& type,
                    const std::string& id, const std::string& sensor,
                    size_t retries, std::chrono::milliseconds delay) const

{
    std::ofstream ofs;
    auto fullPath = sysfs::make_sysfs_path(p, type, id, sensor);

    ofs.exceptions(std::ofstream::failbit | std::ofstream::badbit |
                   std::ofstream::eofbit);

    // See comments in the read method for an explanation of the odd exception
    // handling behavior here.

    while (true)
    {
        try
        {
            errno = 0;
            if (!ofs.is_open())
                ofs.open(fullPath);
            ofs.clear();
            ofs.seekp(0);
            ofs << val;
            ofs.flush();
        }
        catch (const std::exception& e)
        {
            auto rc = errno;

            if (!rc)
            {
                throw;
            }

            if (rc == ENOENT)
            {
                exit(0);
            }

            if (0 == std::count(retryableErrors.begin(), retryableErrors.end(),
                                rc) ||
                !retries)
            {
                // Not a retryable error or out of retries.

                // Work around GCC bugs 53984 and 66145 for callers by
                // explicitly raising system_error here.
                throw std::system_error(rc, std::generic_category());
            }

            --retries;
            std::this_thread::sleep_for(delay);
            continue;
        }
        break;
    }
}

std::string HwmonIO::path() const
{
    return p;
}

} // namespace hwmonio
