/**
 * Copyright © 2017 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 "pmbus.hpp"

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

#include <filesystem>
#include <fstream>

namespace phosphor
{
namespace pmbus
{

using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
using namespace sdbusplus::xyz::openbmc_project::Common::Device::Error;
namespace fs = std::filesystem;

/**
 * @brief Helper to close a file handle
 */
struct FileCloser
{
    void operator()(FILE* fp) const
    {
        fclose(fp);
    }
};

std::string PMBus::insertPageNum(const std::string& templateName, size_t page)
{
    auto name = templateName;

    // insert the page where the P was
    auto pos = name.find('P');
    if (pos != std::string::npos)
    {
        name.replace(pos, 1, std::to_string(page));
    }

    return name;
}

fs::path PMBus::getPath(Type type)
{
    switch (type)
    {
        default:
        /* fall through */
        case Type::Base:
            return basePath;
            break;
        case Type::Hwmon:
            return basePath / "hwmon" / hwmonDir;
            break;
        case Type::Debug:
            return debugPath / "pmbus" / hwmonDir;
            break;
        case Type::DeviceDebug:
        {
            auto dir = driverName + "." + std::to_string(instance);
            return debugPath / dir;
            break;
        }
        case Type::HwmonDeviceDebug:
            return debugPath / "pmbus" / hwmonDir / getDeviceName();
            break;
    }
}

std::string PMBus::getDeviceName()
{
    std::string name;
    std::ifstream file;
    auto path = basePath / "name";

    file.exceptions(std::ifstream::failbit | std::ifstream::badbit |
                    std::ifstream::eofbit);
    try
    {
        file.open(path);
        file >> name;
    }
    catch (const std::exception& e)
    {
        lg2::error("Unable to read PMBus device name PATH={PATH}", "PATH",
                   path);
    }

    return name;
}

bool PMBus::readBitInPage(const std::string& name, size_t page, Type type)
{
    auto pagedBit = insertPageNum(name, page);
    return readBit(pagedBit, type);
}

bool PMBus::readBit(const std::string& name, Type type)
{
    unsigned long int value = 0;
    std::ifstream file;
    fs::path path = getPath(type);

    path /= name;

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

    try
    {
        char* err = nullptr;
        std::string val(1, '\0');

        file.open(path);
        file.read(&val[0], 1);

        value = strtoul(val.c_str(), &err, 10);

        if (*err)
        {
            lg2::error(
                "Invalid character in sysfs file FILE={FILE} CONTENTS={CONTENTS}",
                "FILE", path, "CONTENTS", val);

            // Catch below and handle as a read failure
            elog<InternalFailure>();
        }
    }
    catch (const std::exception& e)
    {
        auto rc = errno;

        lg2::error(
            "Failed to read sysfs file errno={ERRNO} FILENAME={FILENAME}",
            "ERRNO", rc, "FILENAME", path);

        using metadata = xyz::openbmc_project::Common::Device::ReadFailure;

        elog<ReadFailure>(
            metadata::CALLOUT_ERRNO(rc),
            metadata::CALLOUT_DEVICE_PATH(fs::canonical(basePath).c_str()));
    }

    return value != 0;
}

bool PMBus::exists(const std::string& name, Type type)
{
    auto path = getPath(type);
    path /= name;
    return fs::exists(path);
}

uint64_t PMBus::read(const std::string& name, Type type, bool errTrace)
{
    uint64_t data = 0;
    std::ifstream file;
    auto path = getPath(type);
    path /= name;

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

    try
    {
        file.open(path);
        file >> std::hex >> data;
    }
    catch (const std::exception& e)
    {
        auto rc = errno;

        if (errTrace)
        {
            lg2::error(
                "Failed to read sysfs file errno={ERRNO} FILENAME={FILENAME}",
                "ERRNO", rc, "FILENAME", path);

            using metadata = xyz::openbmc_project::Common::Device::ReadFailure;

            elog<ReadFailure>(
                metadata::CALLOUT_ERRNO(rc),
                metadata::CALLOUT_DEVICE_PATH(fs::canonical(basePath).c_str()));
        }
        else
        {
            throw ReadFailure();
        }
    }

    return data;
}

std::string PMBus::readString(const std::string& name, Type type)
{
    std::string data;
    std::ifstream file;
    auto path = getPath(type);
    path /= name;

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

    try
    {
        file.open(path);
        file >> data;
    }
    catch (const std::exception& e)
    {
        auto rc = errno;
        lg2::error(
            "Failed to read sysfs file errno={ERRNO} FILENAME={FILENAME}",
            "ERRNO", rc, "FILENAME", path);

        using metadata = xyz::openbmc_project::Common::Device::ReadFailure;

        elog<ReadFailure>(
            metadata::CALLOUT_ERRNO(rc),
            metadata::CALLOUT_DEVICE_PATH(fs::canonical(basePath).c_str()));
    }

    return data;
}

std::vector<uint8_t> PMBus::readBinary(const std::string& name, Type type,
                                       size_t length)
{
    auto path = getPath(type) / name;

    // Use C style IO because it's easier to handle telling the difference
    // between hitting EOF or getting an actual error.
    std::unique_ptr<FILE, FileCloser> file{fopen(path.c_str(), "rb")};

    if (file)
    {
        std::vector<uint8_t> data(length, 0);

        auto bytes =
            fread(data.data(), sizeof(decltype(data[0])), length, file.get());

        if (bytes != length)
        {
            // If hit EOF, just return the amount of data that was read.
            if (feof(file.get()))
            {
                data.erase(data.begin() + bytes, data.end());
            }
            else if (ferror(file.get()))
            {
                auto rc = errno;
                lg2::error(
                    "Failed to read sysfs file errno={ERRNO} FILENAME={FILENAME}",
                    "ERRNO", rc, "FILENAME", path);
                using metadata =
                    xyz::openbmc_project::Common::Device::ReadFailure;

                elog<ReadFailure>(metadata::CALLOUT_ERRNO(rc),
                                  metadata::CALLOUT_DEVICE_PATH(
                                      fs::canonical(basePath).c_str()));
            }
        }
        return data;
    }

    return std::vector<uint8_t>{};
}

void PMBus::write(const std::string& name, int value, Type type)
{
    std::ofstream file;
    fs::path path = getPath(type);

    path /= name;

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

    try
    {
        file.open(path);
        file << value;
    }
    catch (const std::exception& e)
    {
        auto rc = errno;
        lg2::error(
            "Failed to write sysfs file errno={ERRNO} FILENAME={FILENAME}",
            "ERRNO", rc, "FILENAME", path);

        using metadata = xyz::openbmc_project::Common::Device::WriteFailure;

        elog<WriteFailure>(
            metadata::CALLOUT_ERRNO(rc),
            metadata::CALLOUT_DEVICE_PATH(fs::canonical(basePath).c_str()));
    }
}

void PMBus::writeBinary(const std::string& name, std::vector<uint8_t> data,
                        Type type)
{
    std::ofstream file;
    fs::path path = getPath(type);

    path /= name;

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

    try
    {
        // I need to specify binary mode when I construct the ofstream
        file.open(path, std::ios::out | std::ios_base::binary);
        lg2::debug("Write data to sysfs file FILENAME={FILENAME}", "FILENAME",
                   path);
        file.write(reinterpret_cast<const char*>(&data[0]), data.size());
    }
    catch (const std::exception& e)
    {
        auto rc = errno;
        lg2::error(
            "Failed to write binary data to sysfs file errno={ERRNO} FILENAME={FILENAME}",
            "ERRNO", rc, "FILENAME", path);

        using metadata = xyz::openbmc_project::Common::Device::WriteFailure;

        elog<WriteFailure>(
            metadata::CALLOUT_ERRNO(rc),
            metadata::CALLOUT_DEVICE_PATH(fs::canonical(basePath).c_str()));
    }
}

void PMBus::findHwmonDir()
{
    fs::path path{basePath};
    path /= "hwmon";

    // Make sure the directory exists, otherwise for things that can be
    // dynamically present or not present an exception will be thrown if the
    // hwmon directory is not there, resulting in a program termination.
    if (fs::is_directory(path))
    {
        // look for <basePath>/hwmon/hwmonN/
        for (auto& f : fs::directory_iterator(path))
        {
            if ((f.path().filename().string().find("hwmon") !=
                 std::string::npos) &&
                (fs::is_directory(f.path())))
            {
                hwmonDir = f.path().filename();
                break;
            }
        }
    }

    // Don't really want to crash here, just log it
    // and let accesses fail later
    if (hwmonDir.empty())
    {
        lg2::info("Unable to find hwmon directory in device base path "
                  "DEVICE_PATH={DEVICE_PATH}",
                  "DEVICE_PATH", basePath);
    }
}

std::unique_ptr<PMBusBase> PMBus::createPMBus(std::uint8_t bus,
                                              const std::string& address)
{
    const std::string physpath = {
        "/sys/bus/i2c/devices/" + std::to_string(bus) + "-" + address};
    auto interface = std::make_unique<PMBus>(physpath);

    return interface;
}

std::unique_ptr<PMBusBase> createPMBus(std::uint8_t bus,
                                       const std::string& address)
{
    return PMBus::createPMBus(bus, address);
}

} // namespace pmbus
} // namespace phosphor
