/**
 * Copyright © 2019 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 "config.h"

#include "pel.hpp"

#include "bcd_time.hpp"
#include "extended_user_data.hpp"
#include "extended_user_header.hpp"
#include "failing_mtms.hpp"
#include "fru_identity.hpp"
#include "json_utils.hpp"
#include "log_id.hpp"
#include "pel_rules.hpp"
#include "pel_values.hpp"
#include "section_factory.hpp"
#include "src.hpp"
#include "stream.hpp"
#include "user_data_formats.hpp"

#ifdef PEL_ENABLE_PHAL
#include "phal_service_actions.hpp"
#include "sbe_ffdc_handler.hpp"
#endif

#include <sys/stat.h>
#include <unistd.h>

#include <phosphor-logging/lg2.hpp>

#include <format>
#include <iostream>

namespace openpower
{
namespace pels
{
namespace pv = openpower::pels::pel_values;

constexpr auto unknownValue = "Unknown";

PEL::PEL(const message::Entry& regEntry, uint32_t obmcLogID, uint64_t timestamp,
         phosphor::logging::Entry::Level severity,
         const AdditionalData& additionalData, const PelFFDC& ffdcFilesIn,
         const DataInterfaceBase& dataIface, const JournalBase& journal)
{
    // No changes in input, for non SBE error related requests
    PelFFDC ffdcFiles = ffdcFilesIn;

#ifdef PEL_ENABLE_PHAL
    // Add sbe ffdc processed data into ffdcfiles.
    namespace sbe = openpower::pels::sbe;
    auto processReq = std::any_of(ffdcFiles.begin(), ffdcFiles.end(),
                                  [](const auto& file) {
        return file.format == UserDataFormat::custom &&
               file.subType == sbe::sbeFFDCSubType;
    });
    // sbeFFDC can't be destroyed until the end of the PEL constructor
    // because it needs to keep around the FFDC Files to be used below.
    std::unique_ptr<sbe::SbeFFDC> sbeFFDCPtr;
    if (processReq)
    {
        sbeFFDCPtr = std::make_unique<sbe::SbeFFDC>(additionalData,
                                                    ffdcFilesIn);
        const auto& sbeFFDCFiles = sbeFFDCPtr->getSbeFFDC();
        ffdcFiles.insert(ffdcFiles.end(), sbeFFDCFiles.begin(),
                         sbeFFDCFiles.end());

        // update pel priority for spare clock failures
        if (auto customSeverity = sbeFFDCPtr->getSeverity())
        {
            severity = customSeverity.value();
        }
    }
#endif

    std::map<std::string, std::vector<std::string>> debugData;
    nlohmann::json callouts;

    _ph = std::make_unique<PrivateHeader>(regEntry.componentID, obmcLogID,
                                          timestamp);
    _uh = std::make_unique<UserHeader>(regEntry, severity, additionalData,
                                       dataIface);

    // Extract any callouts embedded in an FFDC file.
    if (!ffdcFiles.empty())
    {
        try
        {
            callouts = getCalloutJSON(ffdcFiles);
        }
        catch (const std::exception& e)
        {
            debugData.emplace("FFDC file JSON callouts error",
                              std::vector<std::string>{e.what()});
        }
    }

    auto src = std::make_unique<SRC>(regEntry, additionalData, callouts,
                                     dataIface);

    if (!src->getDebugData().empty())
    {
        // Something didn't go as planned
        debugData.emplace("SRC", src->getDebugData());
    }

    auto euh = std::make_unique<ExtendedUserHeader>(dataIface, regEntry, *src);

    _optionalSections.push_back(std::move(src));
    _optionalSections.push_back(std::move(euh));

    auto mtms = std::make_unique<FailingMTMS>(dataIface);
    _optionalSections.push_back(std::move(mtms));

    auto ud = util::makeSysInfoUserDataSection(additionalData, dataIface);
    addUserDataSection(std::move(ud));

    //  Check for pel severity of type - 0x51 = critical error, system
    //  termination and update terminate bit in SRC for pels
    updateTerminateBitInSRCSection();

    // Create a UserData section from AdditionalData.
    if (!additionalData.empty())
    {
        ud = util::makeADUserDataSection(additionalData);
        addUserDataSection(std::move(ud));
    }

    // Add any FFDC files into UserData sections
    for (const auto& file : ffdcFiles)
    {
        ud = util::makeFFDCuserDataSection(regEntry.componentID, file);
        if (!ud)
        {
            // Add this error into the debug data UserData section
            std::ostringstream msg;
            msg << "Could not make PEL FFDC UserData section from file"
                << std::hex << regEntry.componentID << " " << file.subType
                << " " << file.version;
            if (debugData.count("FFDC File"))
            {
                debugData.at("FFDC File").push_back(msg.str());
            }
            else
            {
                debugData.emplace("FFDC File",
                                  std::vector<std::string>{msg.str()});
            }

            continue;
        }

        addUserDataSection(std::move(ud));
    }

#ifdef PEL_ENABLE_PHAL
    auto path = std::string(OBJ_ENTRY) + '/' + std::to_string(obmcLogID);
    openpower::pels::phal::createServiceActions(callouts, path, dataIface,
                                                plid());
#endif

    // Store in the PEL any important debug data created while
    // building the PEL sections.
    if (!debugData.empty())
    {
        nlohmann::json data;
        data["PEL Internal Debug Data"] = debugData;
        ud = util::makeJSONUserDataSection(data);

        addUserDataSection(std::move(ud));

        // Also put in the journal for debug
        for (const auto& [name, msgs] : debugData)
        {
            for (const auto& message : msgs)
            {
                lg2::info("{NAME}: {MSG}", "NAME", name, "MSG", message);
            }
        }
    }

    addJournalSections(regEntry, journal);

    _ph->setSectionCount(2 + _optionalSections.size());

    checkRulesAndFix();
}

PEL::PEL(std::vector<uint8_t>& data) : PEL(data, 0) {}

PEL::PEL(std::vector<uint8_t>& data, uint32_t obmcLogID)
{
    populateFromRawData(data, obmcLogID);
}

void PEL::populateFromRawData(std::vector<uint8_t>& data, uint32_t obmcLogID)
{
    Stream pelData{data};
    _ph = std::make_unique<PrivateHeader>(pelData);
    if (obmcLogID != 0)
    {
        _ph->setOBMCLogID(obmcLogID);
    }

    _uh = std::make_unique<UserHeader>(pelData);

    // Use the section factory to create the rest of the objects
    for (size_t i = 2; i < _ph->sectionCount(); i++)
    {
        auto section = section_factory::create(pelData);
        _optionalSections.push_back(std::move(section));
    }
}

bool PEL::valid() const
{
    bool valid = _ph->valid();

    if (valid)
    {
        valid = _uh->valid();
    }

    if (valid)
    {
        if (!std::all_of(_optionalSections.begin(), _optionalSections.end(),
                         [](const auto& section) { return section->valid(); }))
        {
            valid = false;
        }
    }

    return valid;
}

void PEL::setCommitTime()
{
    auto now = std::chrono::system_clock::now();
    _ph->setCommitTimestamp(getBCDTime(now));
}

void PEL::assignID()
{
    _ph->setID(generatePELID());
}

void PEL::flatten(std::vector<uint8_t>& pelBuffer) const
{
    Stream pelData{pelBuffer};

    if (!valid())
    {
        lg2::warning("Unflattening an invalid PEL");
    }

    _ph->flatten(pelData);
    _uh->flatten(pelData);

    for (auto& section : _optionalSections)
    {
        section->flatten(pelData);
    }
}

std::vector<uint8_t> PEL::data() const
{
    std::vector<uint8_t> pelData;
    flatten(pelData);
    return pelData;
}

size_t PEL::size() const
{
    size_t size = 0;

    if (_ph)
    {
        size += _ph->header().size;
    }

    if (_uh)
    {
        size += _uh->header().size;
    }

    for (const auto& section : _optionalSections)
    {
        size += section->header().size;
    }

    return size;
}

std::optional<SRC*> PEL::primarySRC() const
{
    auto src = std::find_if(_optionalSections.begin(), _optionalSections.end(),
                            [](auto& section) {
        return section->header().id ==
               static_cast<uint16_t>(SectionID::primarySRC);
    });
    if (src != _optionalSections.end())
    {
        return static_cast<SRC*>(src->get());
    }

    return std::nullopt;
}

void PEL::checkRulesAndFix()
{
    // Only fix if the action flags are at their default value which
    // means they weren't specified in the registry.  Otherwise
    // assume the user knows what they are doing.
    if (_uh->actionFlags() == actionFlagsDefault)
    {
        auto [actionFlags, eventType] = pel_rules::check(0, _uh->eventType(),
                                                         _uh->severity());

        _uh->setActionFlags(actionFlags);
        _uh->setEventType(eventType);
    }
}

void PEL::printSectionInJSON(const Section& section, std::string& buf,
                             std::map<uint16_t, size_t>& pluralSections,
                             message::Registry& registry,
                             const std::vector<std::string>& plugins,
                             uint8_t creatorID) const
{
    char tmpB[5];
    uint8_t id[] = {static_cast<uint8_t>(section.header().id >> 8),
                    static_cast<uint8_t>(section.header().id)};
    sprintf(tmpB, "%c%c", id[0], id[1]);
    std::string sectionID(tmpB);
    std::string sectionName = pv::sectionTitles.count(sectionID)
                                  ? pv::sectionTitles.at(sectionID)
                                  : "Unknown Section";

    // Add a count if there are multiple of this type of section
    auto count = pluralSections.find(section.header().id);
    if (count != pluralSections.end())
    {
        sectionName += " " + std::to_string(count->second);
        count->second++;
    }

    if (section.valid())
    {
        std::optional<std::string> json;
        if (sectionID == "PS" || sectionID == "SS")
        {
            json = section.getJSON(registry, plugins, creatorID);
        }
        else if ((sectionID == "UD") || (sectionID == "ED"))
        {
            json = section.getJSON(creatorID, plugins);
        }
        else
        {
            json = section.getJSON(creatorID);
        }

        buf += "\"" + sectionName + "\": {\n";

        if (json)
        {
            buf += *json + "\n},\n";
        }
        else
        {
            jsonInsert(buf, pv::sectionVer,
                       getNumberString("%d", section.header().version), 1);
            jsonInsert(buf, pv::subSection,
                       getNumberString("%d", section.header().subType), 1);
            jsonInsert(buf, pv::createdBy,
                       getNumberString("0x%X", section.header().componentID),
                       1);

            std::vector<uint8_t> data;
            Stream s{data};
            section.flatten(s);
            std::string dstr =
                dumpHex(std::data(data) + SectionHeader::flattenedSize(),
                        data.size() - SectionHeader::flattenedSize(), 2)
                    .get();
            std::string jsonIndent(indentLevel, 0x20);
            buf += jsonIndent + "\"Data\": [\n";
            buf += dstr;
            buf += jsonIndent + "]\n";
            buf += "},\n";
        }
    }
    else
    {
        buf += "\n\"Invalid Section\": [\n    \"invalid\"\n],\n";
    }
}

std::map<uint16_t, size_t> PEL::getPluralSections() const
{
    std::map<uint16_t, size_t> sectionCounts;

    for (const auto& section : optionalSections())
    {
        if (sectionCounts.find(section->header().id) == sectionCounts.end())
        {
            sectionCounts[section->header().id] = 1;
        }
        else
        {
            sectionCounts[section->header().id]++;
        }
    }

    std::map<uint16_t, size_t> sections;
    for (const auto& [id, count] : sectionCounts)
    {
        if (count > 1)
        {
            // Start with 0 here and printSectionInJSON()
            // will increment it as it goes.
            sections.emplace(id, 0);
        }
    }

    return sections;
}

void PEL::toJSON(message::Registry& registry,
                 const std::vector<std::string>& plugins) const
{
    auto sections = getPluralSections();

    std::string buf = "{\n";
    printSectionInJSON(*(_ph.get()), buf, sections, registry, plugins,
                       _ph->creatorID());
    printSectionInJSON(*(_uh.get()), buf, sections, registry, plugins,
                       _ph->creatorID());
    for (auto& section : this->optionalSections())
    {
        printSectionInJSON(*(section.get()), buf, sections, registry, plugins,
                           _ph->creatorID());
    }
    buf += "}";
    std::size_t found = buf.rfind(",");
    if (found != std::string::npos)
        buf.replace(found, 1, "");
    std::cout << buf << std::endl;
}

bool PEL::addUserDataSection(std::unique_ptr<UserData> userData)
{
    if (size() + userData->header().size > _maxPELSize)
    {
        if (userData->shrink(_maxPELSize - size()))
        {
            _optionalSections.push_back(std::move(userData));
        }
        else
        {
            lg2::warning("Could not shrink UserData section. Dropping. "
                         "Section size = {SSIZE}, Component ID = {COMP_ID}, "
                         "Subtype = {SUBTYPE}, Version = {VERSION}",
                         "SSIZE", userData->header().size, "COMP_ID",
                         userData->header().componentID, "SUBTYPE",
                         userData->header().subType, "VERSION",
                         userData->header().version);
            return false;
        }
    }
    else
    {
        _optionalSections.push_back(std::move(userData));
    }
    return true;
}

nlohmann::json PEL::getCalloutJSON(const PelFFDC& ffdcFiles)
{
    nlohmann::json callouts;

    for (const auto& file : ffdcFiles)
    {
        if ((file.format == UserDataFormat::json) &&
            (file.subType == jsonCalloutSubtype))
        {
            auto data = util::readFD(file.fd);
            if (data.empty())
            {
                throw std::runtime_error{
                    "Could not get data from JSON callout file descriptor"};
            }

            std::string jsonString{data.begin(), data.begin() + data.size()};

            callouts = nlohmann::json::parse(jsonString);
            break;
        }
    }

    return callouts;
}

bool PEL::isHwCalloutPresent() const
{
    auto pSRC = primarySRC();
    if (!pSRC)
    {
        return false;
    }

    bool calloutPresent = false;
    if ((*pSRC)->callouts())
    {
        for (auto& i : (*pSRC)->callouts()->callouts())
        {
            if (((*i).fruIdentity()))
            {
                auto& fruId = (*i).fruIdentity();
                if ((*fruId).failingComponentType() ==
                    src::FRUIdentity::hardwareFRU)
                {
                    calloutPresent = true;
                    break;
                }
            }
        }
    }

    return calloutPresent;
}

void PEL::updateSysInfoInExtendedUserDataSection(
    const DataInterfaceBase& dataIface)
{
    const AdditionalData additionalData;

    // Check for PEL from Hostboot
    if (_ph->creatorID() == static_cast<uint8_t>(CreatorID::hostboot))
    {
        // Get the ED section from PEL
        auto op = std::find_if(_optionalSections.begin(),
                               _optionalSections.end(), [](auto& section) {
            return section->header().id ==
                   static_cast<uint16_t>(SectionID::extUserData);
        });

        // Check for ED section found and its not the last section of PEL
        if (op != _optionalSections.end())
        {
            // Get the extended user data class mapped to found section
            auto extUserData = static_cast<ExtendedUserData*>(op->get());

            // Check for the creator ID is for OpenBMC
            if (extUserData->creatorID() ==
                static_cast<uint8_t>(CreatorID::openBMC))
            {
                // Update subtype and component id
                auto subType = static_cast<uint8_t>(UserDataFormat::json);
                auto componentId =
                    static_cast<uint16_t>(ComponentID::phosphorLogging);

                // Update system data to ED section
                auto ud = util::makeSysInfoUserDataSection(additionalData,
                                                           dataIface, false);
                extUserData->updateDataSection(subType, componentId,
                                               ud->data());
            }
        }
    }
}

bool PEL::getDeconfigFlag() const
{
    auto creator = static_cast<CreatorID>(_ph->creatorID());

    if ((creator == CreatorID::openBMC) || (creator == CreatorID::hostboot))
    {
        auto src = primarySRC();
        return (*src)->getErrorStatusFlag(SRC::ErrorStatusFlags::deconfigured);
    }
    return false;
}

bool PEL::getGuardFlag() const
{
    auto creator = static_cast<CreatorID>(_ph->creatorID());

    if ((creator == CreatorID::openBMC) || (creator == CreatorID::hostboot))
    {
        auto src = primarySRC();
        return (*src)->getErrorStatusFlag(SRC::ErrorStatusFlags::guarded);
    }
    return false;
}

void PEL::updateTerminateBitInSRCSection()
{
    //  Check for pel severity of type - 0x51 = critical error, system
    //  termination
    if (_uh->severity() == 0x51)
    {
        // Get the primary SRC section
        auto pSRC = primarySRC();
        if (pSRC)
        {
            (*pSRC)->setTerminateBit();
        }
    }
}

void PEL::addJournalSections(const message::Entry& regEntry,
                             const JournalBase& journal)
{
    if (!regEntry.journalCapture)
    {
        return;
    }

    // Write all unwritten journal data to disk.
    journal.sync();

    const auto& jc = regEntry.journalCapture.value();
    std::vector<std::vector<std::string>> allMessages;

    if (std::holds_alternative<size_t>(jc))
    {
        // Get the previous numLines journal entries
        const auto& numLines = std::get<size_t>(jc);
        try
        {
            auto messages = journal.getMessages("", numLines);
            if (!messages.empty())
            {
                allMessages.push_back(std::move(messages));
            }
        }
        catch (const std::exception& e)
        {
            lg2::error("Failed during journal collection: {ERROR}", "ERROR", e);
        }
    }
    else if (std::holds_alternative<message::AppCaptureList>(jc))
    {
        // Get journal entries based on the syslog id field.
        const auto& sections = std::get<message::AppCaptureList>(jc);
        for (const auto& [syslogID, numLines] : sections)
        {
            try
            {
                auto messages = journal.getMessages(syslogID, numLines);
                if (!messages.empty())
                {
                    allMessages.push_back(std::move(messages));
                }
            }
            catch (const std::exception& e)
            {
                lg2::error("Failed during journal collection: {ERROR}", "ERROR",
                           e);
            }
        }
    }

    // Create the UserData sections
    for (const auto& messages : allMessages)
    {
        auto buffer = util::flattenLines(messages);

        // If the buffer is way too big, it can overflow the uint16_t
        // PEL section size field that is checked below so do a cursory
        // check here.
        if (buffer.size() > _maxPELSize)
        {
            lg2::warning(
                "Journal UserData section does not fit in PEL, dropping. "
                "PEL size = {PEL_SIZE}, data size = {DATA_SIZE}",
                "PEL_SIZE", size(), "DATA_SIZE", buffer.size());
            continue;
        }

        // Sections must be 4 byte aligned.
        while (buffer.size() % 4 != 0)
        {
            buffer.push_back(0);
        }

        auto ud = std::make_unique<UserData>(
            static_cast<uint16_t>(ComponentID::phosphorLogging),
            static_cast<uint8_t>(UserDataFormat::text),
            static_cast<uint8_t>(UserDataFormatVersion::text), buffer);

        if (size() + ud->header().size <= _maxPELSize)
        {
            _optionalSections.push_back(std::move(ud));
        }
        else
        {
            // Don't attempt to shrink here since we'd be dropping the
            // most recent journal entries which would be confusing.
            lg2::warning(
                "Journal UserData section does not fit in PEL, dropping. "
                "PEL size = {PEL_SIZE}, data size = {DATA_SIZE}",
                "PEL_SIZE", size(), "DATA_SIZE", buffer.size());
            ud.reset();
            continue;
        }
    }
}

namespace util
{

std::unique_ptr<UserData> makeJSONUserDataSection(const nlohmann::json& json)
{
    auto jsonString = json.dump();
    std::vector<uint8_t> jsonData(jsonString.begin(), jsonString.end());

    // Pad to a 4 byte boundary
    while ((jsonData.size() % 4) != 0)
    {
        jsonData.push_back(0);
    }

    return std::make_unique<UserData>(
        static_cast<uint16_t>(ComponentID::phosphorLogging),
        static_cast<uint8_t>(UserDataFormat::json),
        static_cast<uint8_t>(UserDataFormatVersion::json), jsonData);
}

std::unique_ptr<UserData> makeADUserDataSection(const AdditionalData& ad)
{
    assert(!ad.empty());
    nlohmann::json json;

    // Remove the 'ESEL' entry, as it contains a full PEL in the value.
    if (ad.getValue("ESEL"))
    {
        auto newAD = ad;
        newAD.remove("ESEL");
        json = newAD.toJSON();
    }
    else
    {
        json = ad.toJSON();
    }

    return makeJSONUserDataSection(json);
}

void addProcessNameToJSON(nlohmann::json& json,
                          const std::optional<std::string>& pid,
                          const DataInterfaceBase& dataIface)
{
    std::string name{unknownValue};

    try
    {
        if (pid)
        {
            auto n = dataIface.getProcessName(*pid);
            if (n)
            {
                name = *n;
            }
        }
    }
    catch (const std::exception& e)
    {}

    if (pid)
    {
        json["Process Name"] = std::move(name);
    }
}

void addBMCFWVersionIDToJSON(nlohmann::json& json,
                             const DataInterfaceBase& dataIface)
{
    auto id = dataIface.getBMCFWVersionID();
    if (id.empty())
    {
        id = unknownValue;
    }

    json["FW Version ID"] = std::move(id);
}

std::string lastSegment(char separator, std::string data)
{
    auto pos = data.find_last_of(separator);
    if (pos != std::string::npos)
    {
        data = data.substr(pos + 1);
    }

    return data;
}

void addIMKeyword(nlohmann::json& json, const DataInterfaceBase& dataIface)
{
    auto keyword = dataIface.getSystemIMKeyword();

    std::string value{};

    std::for_each(keyword.begin(), keyword.end(), [&](const auto& byte) {
        value += std::format("{:02X}", byte);
    });

    json["System IM"] = value;
}

void addStatesToJSON(nlohmann::json& json, const DataInterfaceBase& dataIface)
{
    json["BMCState"] = lastSegment('.', dataIface.getBMCState());
    json["ChassisState"] = lastSegment('.', dataIface.getChassisState());
    json["HostState"] = lastSegment('.', dataIface.getHostState());
    json["BootState"] = lastSegment('.', dataIface.getBootState());
}

void addBMCUptime(nlohmann::json& json, const DataInterfaceBase& dataIface)
{
    auto seconds = dataIface.getUptimeInSeconds();
    if (seconds)
    {
        json["BMCUptime"] = dataIface.getBMCUptime(*seconds);
    }
    else
    {
        json["BMCUptime"] = "";
    }
    json["BMCLoad"] = dataIface.getBMCLoadAvg();
}

std::unique_ptr<UserData>
    makeSysInfoUserDataSection(const AdditionalData& ad,
                               const DataInterfaceBase& dataIface,
                               bool addUptime)
{
    nlohmann::json json;

    addProcessNameToJSON(json, ad.getValue("_PID"), dataIface);
    addBMCFWVersionIDToJSON(json, dataIface);
    addIMKeyword(json, dataIface);
    addStatesToJSON(json, dataIface);

    if (addUptime)
    {
        addBMCUptime(json, dataIface);
    }

    return makeJSONUserDataSection(json);
}

std::vector<uint8_t> readFD(int fd)
{
    std::vector<uint8_t> data;

    // Get the size
    struct stat s;
    int r = fstat(fd, &s);
    if (r != 0)
    {
        auto e = errno;
        lg2::error("Could not get FFDC file size from FD, errno = {ERRNO}",
                   "ERRNO", e);
        return data;
    }

    if (0 == s.st_size)
    {
        lg2::error("FFDC file is empty");
        return data;
    }

    data.resize(s.st_size);

    // Make sure its at the beginning, as maybe another
    // extension already used it.
    r = lseek(fd, 0, SEEK_SET);
    if (r == -1)
    {
        auto e = errno;
        lg2::error("Could not seek to beginning of FFDC file, errno = {ERRNO}",
                   "ERRNO", e);
        return data;
    }

    r = read(fd, data.data(), s.st_size);
    if (r == -1)
    {
        auto e = errno;
        lg2::error("Could not read FFDC file, errno = {ERRNO}", "ERRNO", e);
    }
    else if (r != s.st_size)
    {
        lg2::warning("Could not read full FFDC file. "
                     "File size = {FSIZE}, Size read = {SIZE_READ}",
                     "FSIZE", s.st_size, "SIZE_READ", r);
    }

    return data;
}

std::unique_ptr<UserData> makeFFDCuserDataSection(uint16_t componentID,
                                                  const PelFFDCfile& file)
{
    auto data = readFD(file.fd);

    if (data.empty())
    {
        return std::unique_ptr<UserData>();
    }

    // The data needs 4 Byte alignment, and save amount padded for the
    // CBOR case.
    uint32_t pad = 0;
    while (data.size() % 4)
    {
        data.push_back(0);
        pad++;
    }

    // For JSON, CBOR, and Text use our component ID, subType, and version,
    // otherwise use the supplied ones.
    uint16_t compID = static_cast<uint16_t>(ComponentID::phosphorLogging);
    uint8_t subType{};
    uint8_t version{};

    switch (file.format)
    {
        case UserDataFormat::json:
            subType = static_cast<uint8_t>(UserDataFormat::json);
            version = static_cast<uint8_t>(UserDataFormatVersion::json);
            break;
        case UserDataFormat::cbor:
            subType = static_cast<uint8_t>(UserDataFormat::cbor);
            version = static_cast<uint8_t>(UserDataFormatVersion::cbor);

            // The CBOR parser will fail on the extra pad bytes since they
            // aren't CBOR.  Add the amount we padded to the end and other
            // code will remove it all before parsing.
            {
                data.resize(data.size() + 4);
                Stream stream{data};
                stream.offset(data.size() - 4);
                stream << pad;
            }

            break;
        case UserDataFormat::text:
            subType = static_cast<uint8_t>(UserDataFormat::text);
            version = static_cast<uint8_t>(UserDataFormatVersion::text);
            break;
        case UserDataFormat::custom:
        default:
            // Use the passed in values
            compID = componentID;
            subType = file.subType;
            version = file.version;
            break;
    }

    return std::make_unique<UserData>(compID, subType, version, data);
}

std::vector<uint8_t> flattenLines(const std::vector<std::string>& lines)
{
    std::vector<uint8_t> out;

    for (const auto& line : lines)
    {
        out.insert(out.end(), line.begin(), line.end());

        if (out.back() != '\n')
        {
            out.push_back('\n');
        }
    }

    return out;
}

} // namespace util

} // namespace pels
} // namespace openpower
