/**
 * 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 "../bcd_time.hpp"
#include "../json_utils.hpp"
#include "../paths.hpp"
#include "../pel.hpp"
#include "../pel_types.hpp"
#include "../pel_values.hpp"

#include <Python.h>

#include <CLI/CLI.hpp>
#include <bitset>
#include <fstream>
#include <iostream>
#include <phosphor-logging/log.hpp>
#include <regex>
#include <string>
#include <xyz/openbmc_project/Common/File/error.hpp>

namespace fs = std::filesystem;
using namespace phosphor::logging;
using namespace openpower::pels;
using sdbusplus::exception::SdBusError;
namespace file_error = sdbusplus::xyz::openbmc_project::Common::File::Error;
namespace message = openpower::pels::message;
namespace pv = openpower::pels::pel_values;

const uint8_t critSysTermSeverity = 0x51;

using PELFunc = std::function<void(const PEL&, bool hexDump)>;
message::Registry registry(getPELReadOnlyDataPath() / message::registryFileName,
                           false);
namespace service
{
constexpr auto logging = "xyz.openbmc_project.Logging";
} // namespace service

namespace interface
{
constexpr auto deleteObj = "xyz.openbmc_project.Object.Delete";
constexpr auto deleteAll = "xyz.openbmc_project.Collection.DeleteAll";
} // namespace interface

namespace object_path
{
constexpr auto logEntry = "/xyz/openbmc_project/logging/entry/";
constexpr auto logging = "/xyz/openbmc_project/logging";
} // namespace object_path

/**
 * @brief helper function to get PEL commit timestamp from file name
 * @retrun BCDTime - PEL commit timestamp
 * @param[in] std::string - file name
 */
BCDTime fileNameToTimestamp(const std::string& fileName)
{
    std::string token = fileName.substr(0, fileName.find("_"));
    int i = 0;
    BCDTime tmp;
    if (token.length() >= 14)
    {
        try
        {
            tmp.yearMSB = std::stoi(token.substr(i, 2), 0, 16);
        }
        catch (std::exception& err)
        {
            std::cout << "Conversion failure: " << err.what() << std::endl;
        }
        i += 2;
        try
        {
            tmp.yearLSB = std::stoi(token.substr(i, 2), 0, 16);
        }
        catch (std::exception& err)
        {
            std::cout << "Conversion failure: " << err.what() << std::endl;
        }
        i += 2;
        try
        {
            tmp.month = std::stoi(token.substr(i, 2), 0, 16);
        }
        catch (std::exception& err)
        {
            std::cout << "Conversion failure: " << err.what() << std::endl;
        }
        i += 2;
        try
        {
            tmp.day = std::stoi(token.substr(i, 2), 0, 16);
        }
        catch (std::exception& err)
        {
            std::cout << "Conversion failure: " << err.what() << std::endl;
        }
        i += 2;
        try
        {
            tmp.hour = std::stoi(token.substr(i, 2), 0, 16);
        }
        catch (std::exception& err)
        {
            std::cout << "Conversion failure: " << err.what() << std::endl;
        }
        i += 2;
        try
        {
            tmp.minutes = std::stoi(token.substr(i, 2), 0, 16);
        }
        catch (std::exception& err)
        {
            std::cout << "Conversion failure: " << err.what() << std::endl;
        }
        i += 2;
        try
        {
            tmp.seconds = std::stoi(token.substr(i, 2), 0, 16);
        }
        catch (std::exception& err)
        {
            std::cout << "Conversion failure: " << err.what() << std::endl;
        }
        i += 2;
        try
        {
            tmp.hundredths = std::stoi(token.substr(i, 2), 0, 16);
        }
        catch (std::exception& err)
        {
            std::cout << "Conversion failure: " << err.what() << std::endl;
        }
    }
    return tmp;
}

/**
 * @brief helper function to get PEL id from file name
 * @retrun uint32_t - PEL id
 * @param[in] std::string - file name
 */
uint32_t fileNameToPELId(const std::string& fileName)
{
    uint32_t num = 0;
    try
    {
        num = std::stoi(fileName.substr(fileName.find("_") + 1), 0, 16);
    }
    catch (std::exception& err)
    {
        std::cout << "Conversion failure: " << err.what() << std::endl;
    }
    return num;
}

/**
 * @brief helper function to check string suffix
 * @retrun bool - true with suffix matches
 * @param[in] std::string - string to check for suffix
 * @param[in] std::string - suffix string
 */
bool ends_with(const std::string& str, const std::string& end)
{
    size_t slen = str.size(), elen = end.size();
    if (slen < elen)
        return false;
    while (elen)
    {
        if (str[--slen] != end[--elen])
            return false;
    }
    return true;
}

/**
 * @brief get data form raw PEL file.
 * @param[in] std::string Name of file with raw PEL
 * @return std::vector<uint8_t> char vector read from raw PEL file.
 */
std::vector<uint8_t> getFileData(const std::string& name)
{
    std::ifstream file(name, std::ifstream::in);
    if (file.good())
    {
        std::vector<uint8_t> data{std::istreambuf_iterator<char>(file),
                                  std::istreambuf_iterator<char>()};
        return data;
    }
    else
    {
        return {};
    }
}

/**
 * @brief Initialize Python interpreter and gather all UD parser modules under
 *        the paths found in Python sys.path and the current user directory.
 *        This is to prevent calling a non-existant module which causes Python
 *        to print an import error message and breaking JSON output.
 *
 * @return std::vector<std::string> Vector of plugins found in filesystem
 */
std::vector<std::string> getPlugins()
{
    Py_Initialize();
    std::vector<std::string> plugins;
    std::vector<std::string> siteDirs;
    std::array<std::string, 2> parserDirs = {"udparsers", "srcparsers"};
    PyObject* pName = PyUnicode_FromString("sys");
    PyObject* pModule = PyImport_Import(pName);
    Py_XDECREF(pName);
    PyObject* pDict = PyModule_GetDict(pModule);
    Py_XDECREF(pModule);
    PyObject* pResult = PyDict_GetItemString(pDict, "path");
    PyObject* pValue = PyUnicode_FromString(".");
    PyList_Append(pResult, pValue);
    Py_XDECREF(pValue);
    auto list_size = PyList_Size(pResult);
    for (auto i = 0; i < list_size; i++)
    {
        PyObject* item = PyList_GetItem(pResult, i);
        PyObject* pBytes = PyUnicode_AsEncodedString(item, "utf-8", "~E~");
        const char* output = PyBytes_AS_STRING(pBytes);
        Py_XDECREF(pBytes);
        std::string tmpStr(output);
        siteDirs.push_back(tmpStr);
    }
    for (const auto& dir : siteDirs)
    {
        for (const auto& parserDir : parserDirs)
        {
            if (fs::exists(dir + "/" + parserDir))
            {
                for (const auto& entry :
                     fs::directory_iterator(dir + "/" + parserDir))
                {
                    if (entry.is_directory() and
                        fs::exists(entry.path().string() + "/" +
                                   entry.path().stem().string() + ".py"))
                    {
                        plugins.push_back(entry.path().stem());
                    }
                }
            }
        }
    }
    return plugins;
}

/**
 * @brief Creates JSON string of a PEL entry if fullPEL is false or prints to
 *        stdout the full PEL in JSON if fullPEL is true
 * @param[in] itr - std::map iterator of <uint32_t, BCDTime>
 * @param[in] hidden - Boolean to include hidden PELs
 * @param[in] includeInfo - Boolean to include informational PELs
 * @param[in] critSysTerm - Boolean to include critical error and system
 * termination PELs
 * @param[in] fullPEL - Boolean to print full JSON representation of PEL
 * @param[in] foundPEL - Boolean to check if any PEL is present
 * @param[in] scrubRegex - SRC regex object
 * @param[in] plugins - Vector of strings of plugins found in filesystem
 * @param[in] hexDump - Boolean to print hexdump of PEL instead of JSON
 * @return std::string - JSON string of PEL entry (empty if fullPEL is true)
 */
template <typename T>
std::string genPELJSON(T itr, bool hidden, bool includeInfo, bool critSysTerm,
                       bool fullPEL, bool& foundPEL,
                       const std::optional<std::regex>& scrubRegex,
                       const std::vector<std::string>& plugins, bool hexDump)
{
    std::size_t found;
    std::string val;
    char tmpValStr[50];
    std::string listStr;
    char name[50];
    sprintf(name, "%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X_%.8X", itr.second.yearMSB,
            itr.second.yearLSB, itr.second.month, itr.second.day,
            itr.second.hour, itr.second.minutes, itr.second.seconds,
            itr.second.hundredths, itr.first);
    std::string fileName(name);
    fileName = EXTENSION_PERSIST_DIR "/pels/logs/" + fileName;
    try
    {
        std::vector<uint8_t> data = getFileData(fileName);
        if (data.empty())
        {
            log<level::ERR>("Empty PEL file",
                            entry("FILENAME=%s", fileName.c_str()));
            return listStr;
        }
        PEL pel{data};
        if (!pel.valid())
        {
            return listStr;
        }
        if (!includeInfo && pel.userHeader().severity() == 0)
        {
            return listStr;
        }
        if (critSysTerm && pel.userHeader().severity() != critSysTermSeverity)
        {
            return listStr;
        }
        std::bitset<16> actionFlags{pel.userHeader().actionFlags()};
        if (!hidden && actionFlags.test(hiddenFlagBit))
        {
            return listStr;
        }
        if (pel.primarySRC() && scrubRegex)
        {
            val = pel.primarySRC().value()->asciiString();
            if (std::regex_search(trimEnd(val), scrubRegex.value(),
                                  std::regex_constants::match_not_null))
            {
                return listStr;
            }
        }
        if (hexDump)
        {
            std::cout << dumpHex(std::data(pel.data()), pel.size(), 0, false)
                      << std::endl;
        }
        else if (fullPEL)
        {
            if (!foundPEL)
            {
                std::cout << "[\n";
                foundPEL = true;
            }
            else
            {
                std::cout << ",\n\n";
            }
            pel.toJSON(registry, plugins);
        }
        else
        {
            // id
            listStr += "    \"" +
                       getNumberString("0x%X", pel.privateHeader().id()) +
                       "\": {\n";
            // ASCII
            if (pel.primarySRC())
            {
                val = pel.primarySRC().value()->asciiString();
                jsonInsert(listStr, "SRC", trimEnd(val), 2);

                // Registry message
                auto regVal = pel.primarySRC().value()->getErrorDetails(
                    registry, DetailLevel::message, true);
                if (regVal)
                {
                    val = regVal.value();
                    jsonInsert(listStr, "Message", val, 2);
                }
            }
            else
            {
                jsonInsert(listStr, "SRC", "No SRC", 2);
            }

            // platformid
            jsonInsert(listStr, "PLID",
                       getNumberString("0x%X", pel.privateHeader().plid()), 2);

            // creatorid
            std::string creatorID =
                getNumberString("%c", pel.privateHeader().creatorID());
            val = pv::creatorIDs.count(creatorID) ? pv::creatorIDs.at(creatorID)
                                                  : "Unknown Creator ID";
            jsonInsert(listStr, "CreatorID", val, 2);

            // subsystem
            std::string subsystem = pv::getValue(pel.userHeader().subsystem(),
                                                 pel_values::subsystemValues);
            jsonInsert(listStr, "Subsystem", subsystem, 2);

            // commit time
            sprintf(tmpValStr, "%02X/%02X/%02X%02X %02X:%02X:%02X",
                    pel.privateHeader().commitTimestamp().month,
                    pel.privateHeader().commitTimestamp().day,
                    pel.privateHeader().commitTimestamp().yearMSB,
                    pel.privateHeader().commitTimestamp().yearLSB,
                    pel.privateHeader().commitTimestamp().hour,
                    pel.privateHeader().commitTimestamp().minutes,
                    pel.privateHeader().commitTimestamp().seconds);
            jsonInsert(listStr, "Commit Time", tmpValStr, 2);

            // severity
            std::string severity = pv::getValue(pel.userHeader().severity(),
                                                pel_values::severityValues);
            jsonInsert(listStr, "Sev", severity, 2);

            // compID
            jsonInsert(listStr, "CompID",
                       getNumberString(
                           "0x%X", pel.privateHeader().header().componentID),
                       2);

            found = listStr.rfind(",");
            if (found != std::string::npos)
            {
                listStr.replace(found, 1, "");
                listStr += "    },\n";
            }
            foundPEL = true;
        }
    }
    catch (std::exception& e)
    {
        log<level::ERR>("Hit exception while reading PEL File",
                        entry("FILENAME=%s", fileName.c_str()),
                        entry("ERROR=%s", e.what()));
    }
    return listStr;
}

/**
 * @brief Print a list of PELs or a JSON array of PELs
 * @param[in] order - Boolean to print in reverse orser
 * @param[in] hidden - Boolean to include hidden PELs
 * @param[in] includeInfo - Boolean to include informational PELs
 * @param[in] critSysTerm - Boolean to include critical error and system
 * termination PELs
 * @param[in] fullPEL - Boolean to print full PEL into a JSON array
 * @param[in] scrubRegex - SRC regex object
 * @param[in] hexDump - Boolean to print hexdump of PEL instead of JSON
 */
void printPELs(bool order, bool hidden, bool includeInfo, bool critSysTerm,
               bool fullPEL, const std::optional<std::regex>& scrubRegex,
               bool hexDump)
{
    std::string listStr;
    std::map<uint32_t, BCDTime> PELs;
    std::vector<std::string> plugins;
    listStr = "{\n";
    for (auto it = fs::directory_iterator(EXTENSION_PERSIST_DIR "/pels/logs");
         it != fs::directory_iterator(); ++it)
    {
        if (!fs::is_regular_file((*it).path()))
        {
            continue;
        }
        else
        {
            PELs.emplace(fileNameToPELId((*it).path().filename()),
                         fileNameToTimestamp((*it).path().filename()));
        }
    }
    bool foundPEL = false;

    if (fullPEL && !hexDump)
    {
        plugins = getPlugins();
    }
    auto buildJSON = [&listStr, &hidden, &includeInfo, &critSysTerm, &fullPEL,
                      &foundPEL, &scrubRegex, &plugins,
                      &hexDump](const auto& i) {
        listStr += genPELJSON(i, hidden, includeInfo, critSysTerm, fullPEL,
                              foundPEL, scrubRegex, plugins, hexDump);
    };
    if (order)
    {
        std::for_each(PELs.rbegin(), PELs.rend(), buildJSON);
    }
    else
    {
        std::for_each(PELs.begin(), PELs.end(), buildJSON);
    }
    if (hexDump)
    {
        return;
    }
    if (foundPEL)
    {
        if (fullPEL)
        {
            std::cout << "]" << std::endl;
        }
        else
        {
            std::size_t found;
            found = listStr.rfind(",");
            if (found != std::string::npos)
            {
                listStr.replace(found, 1, "");
                listStr += "}\n";
                printf("%s", listStr.c_str());
            }
        }
    }
    else
    {
        std::string emptyJSON = fullPEL ? "[]" : "{}";
        std::cout << emptyJSON << std::endl;
    }
}

/**
 * @brief Calls the function passed in on the PEL with the ID
 *        passed in.
 *
 * @param[in] id - The string version of the PEL or BMC Log ID, either with or
 *                 without the 0x prefix.
 * @param[in] func - The std::function<void(const PEL&, bool hexDump)> function
 *                   to run.
 * @param[in] useBMC - if true, search by BMC Log ID, else search by PEL ID
 * @param[in] hexDump - Boolean to print hexdump of PEL instead of JSON
 */
void callFunctionOnPEL(const std::string& id, const PELFunc& func,
                       bool useBMC = false, bool hexDump = false)
{
    std::string pelID{id};
    if (!useBMC)
    {
        std::transform(pelID.begin(), pelID.end(), pelID.begin(), toupper);

        if (pelID.find("0X") == 0)
        {
            pelID.erase(0, 2);
        }
    }

    bool found = false;

    for (auto it = fs::directory_iterator(EXTENSION_PERSIST_DIR "/pels/logs");
         it != fs::directory_iterator(); ++it)
    {
        // The PEL ID is part of the filename, so use that to find the PEL if
        // "useBMC" is set to false, otherwise we have to search within the PEL

        if (!fs::is_regular_file((*it).path()))
        {
            continue;
        }

        if ((ends_with((*it).path(), pelID) && !useBMC) || useBMC)
        {
            auto data = getFileData((*it).path());
            if (!data.empty())
            {
                PEL pel{data};
                if (!useBMC ||
                    (useBMC && pel.obmcLogID() == std::stoul(id, nullptr, 0)))
                {
                    found = true;
                    try
                    {
                        func(pel, hexDump);
                        break;
                    }
                    catch (std::exception& e)
                    {
                        std::cerr << " Internal function threw an exception: "
                                  << e.what() << "\n";
                        exit(1);
                    }
                }
            }
            else
            {
                std::cerr << "Could not read PEL file\n";
                exit(1);
            }
        }
    }

    if (!found)
    {
        std::cerr << "PEL not found\n";
        exit(1);
    }
}

/**
 * @brief Delete a PEL file.
 *
 * @param[in] id - The PEL ID to delete.
 */
void deletePEL(const std::string& id)
{
    std::string pelID{id};

    std::transform(pelID.begin(), pelID.end(), pelID.begin(), toupper);

    if (pelID.find("0X") == 0)
    {
        pelID.erase(0, 2);
    }

    for (auto it = fs::directory_iterator(EXTENSION_PERSIST_DIR "/pels/logs");
         it != fs::directory_iterator(); ++it)
    {
        if (ends_with((*it).path(), pelID))
        {
            fs::remove((*it).path());
        }
    }
}

/**
 * @brief Delete all PEL files.
 */
void deleteAllPELs()
{
    log<level::INFO>("peltool deleting all event logs");

    for (const auto& entry :
         fs::directory_iterator(EXTENSION_PERSIST_DIR "/pels/logs"))
    {
        fs::remove(entry.path());
    }
}

/**
 * @brief Display a single PEL
 *
 * @param[in] pel - the PEL to display
 * @param[in] hexDump - Boolean to print hexdump of PEL instead of JSON
 */
void displayPEL(const PEL& pel, bool hexDump)
{
    if (pel.valid())
    {
        if (hexDump)
        {
            std::string dstr =
                dumpHex(std::data(pel.data()), pel.size(), 0, false);
            std::cout << dstr << std::endl;
        }
        else
        {
            auto plugins = getPlugins();
            pel.toJSON(registry, plugins);
        }
    }
    else
    {
        std::cerr << "PEL was malformed\n";
        exit(1);
    }
}

/**
 * @brief Print number of PELs
 * @param[in] hidden - Bool to include hidden logs
 * @param[in] includeInfo - Bool to include informational logs
 * @param[in] critSysTerm - Bool to include CritSysTerm
 * @param[in] scrubRegex - SRC regex object
 */
void printPELCount(bool hidden, bool includeInfo, bool critSysTerm,
                   const std::optional<std::regex>& scrubRegex)
{
    std::size_t count = 0;
    for (auto it = fs::directory_iterator(EXTENSION_PERSIST_DIR "/pels/logs");
         it != fs::directory_iterator(); ++it)
    {
        if (!fs::is_regular_file((*it).path()))
        {
            continue;
        }
        std::vector<uint8_t> data = getFileData((*it).path());
        if (data.empty())
        {
            continue;
        }
        PEL pel{data};
        if (!pel.valid())
        {
            continue;
        }
        if (!includeInfo && pel.userHeader().severity() == 0)
        {
            continue;
        }
        if (critSysTerm && pel.userHeader().severity() != critSysTermSeverity)
        {
            continue;
        }
        std::bitset<16> actionFlags{pel.userHeader().actionFlags()};
        if (!hidden && actionFlags.test(hiddenFlagBit))
        {
            continue;
        }
        if (pel.primarySRC() && scrubRegex)
        {
            std::string val = pel.primarySRC().value()->asciiString();
            if (std::regex_search(trimEnd(val), scrubRegex.value(),
                                  std::regex_constants::match_not_null))
            {
                continue;
            }
        }
        count++;
    }
    std::cout << "{\n"
              << "    \"Number of PELs found\": "
              << getNumberString("%d", count) << "\n}\n";
}

/**
 * @brief Generate regex pattern object from file contents
 * @param[in] scrubFile - File containing regex pattern
 * @return std::regex - SRC regex object
 */
std::regex genRegex(std::string& scrubFile)
{
    std::string pattern;
    std::ifstream contents(scrubFile);
    if (contents.fail())
    {
        std::cerr << "Can't open \"" << scrubFile << "\"\n";
        exit(1);
    }
    std::string line;
    while (std::getline(contents, line))
    {
        if (!line.empty())
        {
            pattern.append(line + "|");
        }
    }
    try
    {
        std::regex scrubRegex(pattern, std::regex::icase);
        return scrubRegex;
    }
    catch (std::regex_error& e)
    {
        if (e.code() == std::regex_constants::error_collate)
            std::cerr << "Invalid collating element request\n";
        else if (e.code() == std::regex_constants::error_ctype)
            std::cerr << "Invalid character class\n";
        else if (e.code() == std::regex_constants::error_escape)
            std::cerr << "Invalid escape character or trailing escape\n";
        else if (e.code() == std::regex_constants::error_backref)
            std::cerr << "Invalid back reference\n";
        else if (e.code() == std::regex_constants::error_brack)
            std::cerr << "Mismatched bracket ([ or ])\n";
        else if (e.code() == std::regex_constants::error_paren)
        {
            // to catch return code error_badrepeat when error_paren is retured
            // instead
            size_t pos = pattern.find_first_of("*+?{");
            while (pos != std::string::npos)
            {
                if (pos == 0 || pattern.substr(pos - 1, 1) == "|")
                {
                    std::cerr
                        << "A repetition character (*, ?, +, or {) was not "
                           "preceded by a valid regular expression\n";
                    exit(1);
                }
                pos = pattern.find_first_of("*+?{", pos + 1);
            }
            std::cerr << "Mismatched parentheses (( or ))\n";
        }
        else if (e.code() == std::regex_constants::error_brace)
            std::cerr << "Mismatched brace ({ or })\n";
        else if (e.code() == std::regex_constants::error_badbrace)
            std::cerr << "Invalid range inside a { }\n";
        else if (e.code() == std::regex_constants::error_range)
            std::cerr << "Invalid character range (e.g., [z-a])\n";
        else if (e.code() == std::regex_constants::error_space)
            std::cerr << "Insufficient memory to handle regular expression\n";
        else if (e.code() == std::regex_constants::error_badrepeat)
            std::cerr << "A repetition character (*, ?, +, or {) was not "
                         "preceded by a valid regular expression\n";
        else if (e.code() == std::regex_constants::error_complexity)
            std::cerr << "The requested match is too complex\n";
        else if (e.code() == std::regex_constants::error_stack)
            std::cerr << "Insufficient memory to evaluate a match\n";
        exit(1);
    }
}

static void exitWithError(const std::string& help, const char* err)
{
    std::cerr << "ERROR: " << err << std::endl << help << std::endl;
    exit(-1);
}

int main(int argc, char** argv)
{
    CLI::App app{"OpenBMC PEL Tool"};
    std::string fileName;
    std::string idPEL;
    std::string bmcId;
    std::string idToDelete;
    std::string scrubFile;
    std::optional<std::regex> scrubRegex;
    bool listPEL = false;
    bool listPELDescOrd = false;
    bool hidden = false;
    bool includeInfo = false;
    bool critSysTerm = false;
    bool deleteAll = false;
    bool showPELCount = false;
    bool fullPEL = false;
    bool hexDump = false;

    app.set_help_flag("--help", "Print this help message and exit");
    app.add_option("--file", fileName, "Display a PEL using its Raw PEL file");
    app.add_option("-i, --id", idPEL, "Display a PEL based on its ID");
    app.add_option("--bmc-id", bmcId,
                   "Display a PEL based on its BMC Event ID");
    app.add_flag("-a", fullPEL, "Display all PELs");
    app.add_flag("-l", listPEL, "List PELs");
    app.add_flag("-n", showPELCount, "Show number of PELs");
    app.add_flag("-r", listPELDescOrd, "Reverse order of output");
    app.add_flag("-h", hidden, "Include hidden PELs");
    app.add_flag("-f,--info", includeInfo, "Include informational PELs");
    app.add_flag("-t, --termination", critSysTerm,
                 "List only critical system terminating PELs");
    app.add_option("-d, --delete", idToDelete, "Delete a PEL based on its ID");
    app.add_flag("-D, --delete-all", deleteAll, "Delete all PELs");
    app.add_option("-s, --scrub", scrubFile,
                   "File containing SRC regular expressions to ignore");
    app.add_flag("-x", hexDump, "Display PEL(s) in hexdump instead of JSON");

    CLI11_PARSE(app, argc, argv);

    if (!fileName.empty())
    {
        std::vector<uint8_t> data = getFileData(fileName);
        if (!data.empty())
        {
            PEL pel{data};
            if (hexDump)
            {
                std::string dstr =
                    dumpHex(std::data(pel.data()), pel.size(), 0, false);
                std::cout << dstr << std::endl;
            }
            else
            {
                auto plugins = getPlugins();
                pel.toJSON(registry, plugins);
            }
        }
        else
        {
            exitWithError(app.help("", CLI::AppFormatMode::All),
                          "Raw PEL file can't be read.");
        }
    }
    else if (!idPEL.empty())
    {
        callFunctionOnPEL(idPEL, displayPEL, false, hexDump);
    }
    else if (!bmcId.empty())
    {
        callFunctionOnPEL(bmcId, displayPEL, true, hexDump);
    }
    else if (fullPEL || listPEL)
    {
        if (!scrubFile.empty())
        {
            scrubRegex = genRegex(scrubFile);
        }
        printPELs(listPELDescOrd, hidden, includeInfo, critSysTerm, fullPEL,
                  scrubRegex, hexDump);
    }
    else if (showPELCount)
    {
        if (!scrubFile.empty())
        {
            scrubRegex = genRegex(scrubFile);
        }
        printPELCount(hidden, includeInfo, critSysTerm, scrubRegex);
    }
    else if (!idToDelete.empty())
    {
        deletePEL(idToDelete);
    }
    else if (deleteAll)
    {
        deleteAllPELs();
    }
    else
    {
        std::cout << app.help("", CLI::AppFormatMode::All) << std::endl;
    }
    Py_Finalize();
    return 0;
}
