/**
 * Copyright © 2016 IBM Corporation
 *
 * 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 <algorithm>
#include <cerrno>
#include <cstdlib>
#include <experimental/filesystem>
#include <fstream>
#include <memory>
#include <thread>
#include "sysfs.hpp"

using namespace std::string_literals;
namespace fs = std::experimental::filesystem;

namespace sysfs {

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,
};

static const auto emptyString = ""s;
static constexpr auto ofRoot = "/sys/firmware/devicetree/base";

std::string findPhandleMatch(
        const std::string& iochanneldir,
        const std::string& phandledir)
{
    // TODO: At the moment this method only supports device trees
    // with iio-hwmon nodes with a single sensor.  Typically
    // device trees are defined with all the iio sensors in a
    // single iio-hwmon node so it would be nice to add support
    // for lists of phandles (with variable sized entries) via
    // libfdt or something like that, so that users are not
    // forced into implementing unusual looking device trees
    // with multiple iio-hwmon nodes - one for each sensor.

    fs::path ioChannelsPath{iochanneldir};
    ioChannelsPath /= "io-channels";

    if (!fs::exists(ioChannelsPath))
    {
        return emptyString;
    }

    uint32_t ioChannelsValue;
    std::ifstream ioChannelsFile(ioChannelsPath);

    ioChannelsFile.read(
            reinterpret_cast<char*>(&ioChannelsValue),
            sizeof(ioChannelsValue));

    for (const auto& ofInst : fs::recursive_directory_iterator(phandledir))
    {
        auto path = ofInst.path();
        if ("phandle" != path.filename())
        {
            continue;
        }
        std::ifstream pHandleFile(path);
        uint32_t pHandleValue;

        pHandleFile.read(
                reinterpret_cast<char*>(&pHandleValue),
                sizeof(pHandleValue));

        if (ioChannelsValue == pHandleValue)
        {
            return path;
        }
    }

    return emptyString;
}

std::string findCalloutPath(const std::string& instancePath)
{
    // Follow the hwmon instance (/sys/class/hwmon/hwmon<N>)
    // /sys/devices symlink.
    fs::path devPath{instancePath};
    devPath /= "device";

    try
    {
        devPath = fs::canonical(devPath);
    }
    catch (const std::system_error& e)
    {
        return emptyString;
    }

    // See if the device is backed by the iio-hwmon driver.
    fs::path p{devPath};
    p /= "driver";
    p = fs::canonical(p);

    if (p.filename() != "iio_hwmon")
    {
        // Not backed by iio-hwmon.  The device pointed to
        // is the callout device.
        return devPath;
    }

    // Find the DT path to the iio-hwmon platform device.
    fs::path ofDevPath{devPath};
    ofDevPath /= "of_node";

    try
    {
        ofDevPath = fs::canonical(ofDevPath);
    }
    catch (const std::system_error& e)
    {
        return emptyString;
    }

    // Search /sys/bus/iio/devices for the phandle in io-channels.
    // If a match is found, use the corresponding /sys/devices
    // iio device as the callout device.
    static constexpr auto iioDevices = "/sys/bus/iio/devices";
    for (const auto& iioDev: fs::recursive_directory_iterator(iioDevices))
    {
        p = iioDev.path();
        p /= "of_node";

        try
        {
            p = fs::canonical(p);
        }
        catch (const std::system_error& e)
        {
            continue;
        }

        auto match = findPhandleMatch(ofDevPath, p);
        auto n = match.rfind('/');
        if (n != std::string::npos)
        {
            // This is the iio device referred to by io-channels.
            // Remove iio:device<N>.
            try
            {
                return fs::canonical(iioDev).parent_path();
            }
            catch (const std::system_error& e)
            {
                return emptyString;
            }
        }
    }

    return emptyString;
}

std::string findHwmon(const std::string& ofNode)
{
    static constexpr auto hwmonRoot = "/sys/class/hwmon";

    fs::path fullOfPath{ofRoot};
    fullOfPath /= ofNode;

    for (const auto& hwmonInst : fs::directory_iterator(hwmonRoot))
    {
        auto path = hwmonInst.path();
        path /= "of_node";

        try
        {
            path = fs::canonical(path);
        }
        catch (const std::system_error& e)
        {
            // realpath may encounter ENOENT (Hwmon
            // instances have a nasty habit of
            // going away without warning).
            continue;
        }

        if (path == fullOfPath)
        {
            return hwmonInst.path();
        }

        // Try to find HWMON instance via phandle values.
        // Used for IIO device drivers.
        auto matchpath = findPhandleMatch(path, fullOfPath);
        if (!matchpath.empty())
        {
            return hwmonInst.path();
        }
    }

    return emptyString;
}

namespace hwmonio
{

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.

                // 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
}
// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
