/**
 * 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 <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 (std::exception& e)
    {
        log<level::ERR>("Unable to read PMBus device name",
                        entry("PATH=%s", path.c_str()));
    }

    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 = NULL;
        std::string val{1, '\0'};

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

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

        if (*err)
        {
            log<level::ERR>("Invalid character in sysfs file",
                            entry("FILE=%s", path.c_str()),
                            entry("CONTENTS=%s", val.c_str()));

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

        log<level::ERR>("Failed to read sysfs file",
                        entry("FILENAME=%s", path.c_str()));

        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)
{
    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 (std::exception& e)
    {
        auto rc = errno;
        log<level::ERR>("Failed to read sysfs file",
                        entry("FILENAME=%s", path.c_str()));

        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::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 (std::exception& e)
    {
        auto rc = errno;
        log<level::ERR>("Failed to read sysfs file",
                        entry("FILENAME=%s", path.c_str()));

        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;
                log<level::ERR>("Failed to read sysfs file",
                                entry("FILENAME=%s", path.c_str()));

                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;

        log<level::ERR>("Failed to write sysfs file",
                        entry("FILENAME=%s", path.c_str()));

        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);
        log<level::DEBUG>("Write data to sysfs file",
                          entry("FILENAME=%s", path.c_str()));
        file.write(reinterpret_cast<const char*>(&data[0]), data.size());
    }
    catch (const std::exception& e)
    {
        auto rc = errno;

        log<level::ERR>("Failed to write binary data to sysfs file",
                        entry("FILENAME=%s", path.c_str()));

        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())
    {
        log<level::INFO>("Unable to find hwmon directory "
                         "in device base path",
                         entry("DEVICE_PATH=%s", basePath.c_str()));
    }
}

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
