/**
 * 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
{

int64_t FileSystem::read(const std::string& path) const
{
    int64_t val;
    std::ifstream ifs;
    ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit |
                   std::ifstream::eofbit);

    errno = 0;
    if (!ifs.is_open())
        ifs.open(path);
    ifs.clear();
    ifs.seekg(0);
    ifs >> val;

    return val;
}

void FileSystem::write(const std::string& path, uint32_t value) const
{
    std::ofstream ofs;
    ofs.exceptions(std::ofstream::failbit | std::ofstream::badbit |
                   std::ofstream::eofbit);

    errno = 0;
    if (!ofs.is_open())
        ofs.open(path);
    ofs.clear();
    ofs.seekp(0);
    ofs << value;
    ofs.flush();
}

FileSystem fileSystemImpl;

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, const FileSystemInterface* intf) :
    _p(path), _intf(intf)
{}

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;
    auto fullPath = sysfs::make_sysfs_path(_p, type, id, sensor);

    while (true)
    {
        try
        {
            val = _intf->read(fullPath);
        }
        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.
#if 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

{
    auto fullPath = sysfs::make_sysfs_path(_p, type, id, sensor);

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

    while (true)
    {
        try
        {
            _intf->write(fullPath, val);
        }
        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
