/**
 * 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 (const std::exception& e)
    {
        log<level::ERR>((std::string("Unable to read PMBus device name "
                                     "PATH=") +
                         path.string())
                            .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>((std::string("Invalid character in sysfs file"
                                         " FILE=") +
                             path.string() + std::string(" CONTENTS=") + val)
                                .c_str());

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

        log<level::ERR>((std::string("Failed to read sysfs file "
                                     "errno=") +
                         std::to_string(rc) + std::string(" FILENAME=") +
                         path.string())
                            .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, 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)
        {
            log<level::ERR>((std::string("Failed to read sysfs file "
                                         "errno=") +
                             std::to_string(rc) + " FILENAME=" + path.string())
                                .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()));
        }
        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;
        log<level::ERR>((std::string("Failed to read sysfs file "
                                     "errno=") +
                         std::to_string(rc) + " FILENAME=" + path.string())
                            .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>((std::string("Failed to read sysfs file "
                                             "errno=") +
                                 std::to_string(rc) +
                                 " FILENAME=" + path.string())
                                    .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>((std::string("Failed to write sysfs file "
                                     "errno=") +
                         std::to_string(rc) + " FILENAME=" + path.string())
                            .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>(std::string("Write data to sysfs file "
                                      "FILENAME=" +
                                      path.string())
                              .c_str());
        file.write(reinterpret_cast<const char*>(&data[0]), data.size());
    }
    catch (const std::exception& e)
    {
        auto rc = errno;
        log<level::ERR>(
            (std::string("Failed to write binary data to sysfs file "
                         "errno=") +
             std::to_string(rc) + " FILENAME=" + path.string())
                .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>(std::string("Unable to find hwmon directory "
                                     "in device base path"
                                     " DEVICE_PATH=" +
                                     basePath.string())
                             .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
