/**
 * 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 <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;

using PELFunc = std::function<void(const PEL&)>;
message::Registry registry(getMessageRegistryPath() /
                           message::registryFileName);
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 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] 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
 * @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 fullPEL,
                       bool& foundPEL,
                       const std::optional<std::regex>& scrubRegex)
{
    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;
        }
        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 (fullPEL)
        {
            if (!foundPEL)
            {
                std::cout << "[\n";
                foundPEL = true;
            }
            else
            {
                std::cout << ",\n\n";
            }
            pel.toJSON(registry);
        }
        else
        {
            // id
            listStr += "\t\"" +
                       getNumberString("0x%X", pel.privateHeader().id()) +
                       "\": {\n";
            // ASCII
            if (pel.primarySRC())
            {
                val = pel.primarySRC().value()->asciiString();
                listStr += "\t\t\"SRC\": \"" + trimEnd(val) + "\",\n";
                // Registry message
                auto regVal = pel.primarySRC().value()->getErrorDetails(
                    registry, DetailLevel::message, true);
                if (regVal)
                {
                    val = regVal.value();
                    listStr += "\t\t\"Message\": \"" + val + "\",\n";
                }
            }
            else
            {
                listStr += "\t\t\"SRC\": \"No SRC\",\n";
            }
            // platformid
            listStr += "\t\t\"PLID\": \"" +
                       getNumberString("0x%X", pel.privateHeader().plid()) +
                       "\",\n";
            // creatorid
            std::string creatorID =
                getNumberString("%c", pel.privateHeader().creatorID());
            val = pv::creatorIDs.count(creatorID) ? pv::creatorIDs.at(creatorID)
                                                  : "Unknown Creator ID";
            listStr += "\t\t\"CreatorID\": \"" + val + "\",\n";
            // subsytem
            std::string subsystem = pv::getValue(pel.userHeader().subsystem(),
                                                 pel_values::subsystemValues);
            listStr += "\t\t\"Subsystem\": \"" + subsystem + "\",\n";
            // 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);
            val = std::string(tmpValStr);
            listStr += "\t\t\"Commit Time\": \"" + val + "\",\n";
            // severity
            std::string severity = pv::getValue(pel.userHeader().severity(),
                                                pel_values::severityValues);
            listStr += "\t\t\"Sev\": \"" + severity + "\",\n ";
            // compID
            listStr += "\t\t\"CompID\": \"" +
                       getNumberString(
                           "0x%X", pel.privateHeader().header().componentID) +
                       "\",\n ";
            found = listStr.rfind(",");
            if (found != std::string::npos)
            {
                listStr.replace(found, 1, "");
                listStr += "\t},\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] fullPEL - Boolean to print full PEL into a JSON array
 * @param[in] scrubRegex - SRC regex object
 */
void printPELs(bool order, bool hidden, bool includeInfo, bool fullPEL,
               const std::optional<std::regex>& scrubRegex)
{
    std::string listStr;
    std::map<uint32_t, BCDTime> PELs;
    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;
    auto buildJSON = [&listStr, &hidden, &includeInfo, &fullPEL, &foundPEL,
                      &scrubRegex](const auto& i) {
        listStr +=
            genPELJSON(i, hidden, includeInfo, fullPEL, foundPEL, scrubRegex);
    };
    if (order)
    {
        std::for_each(PELs.rbegin(), PELs.rend(), buildJSON);
    }
    else
    {
        std::for_each(PELs.begin(), PELs.end(), buildJSON);
    }

    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 ID, either with or
 *                 without the 0x prefix.
 * @param[in] func - The std::function<void(const PEL&)> function to run.
 */
void callFunctionOnPEL(const std::string& id, const PELFunc& func)
{
    std::string pelID{id};
    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 (!fs::is_regular_file((*it).path()))
        {
            continue;
        }

        if (ends_with((*it).path(), pelID))
        {
            found = true;

            auto data = getFileData((*it).path());
            if (!data.empty())
            {
                PEL pel{data};

                try
                {
                    func(pel);
                }
                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);
            }
            break;
        }
    }

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

/**
 * @brief Delete a PEL by deleting its corresponding event log.
 *
 * @param[in] pel - The PEL to delete
 */
void deletePEL(const PEL& pel)
{
    std::string path{object_path::logEntry};
    path += std::to_string(pel.obmcLogID());

    try
    {
        auto bus = sdbusplus::bus::new_default();
        auto method = bus.new_method_call(service::logging, path.c_str(),
                                          interface::deleteObj, "Delete");
        auto reply = bus.call(method);
    }
    catch (const SdBusError& e)
    {
        std::cerr << "D-Bus call to delete event log " << pel.obmcLogID()
                  << " failed: " << e.what() << "\n";
        exit(1);
    }
}

/**
 * @brief Delete all PELs by deleting all event logs.
 */
void deleteAllPELs()
{
    try
    {
        // This may move to an audit log some day
        log<level::INFO>("peltool deleting all event logs");

        auto bus = sdbusplus::bus::new_default();
        auto method =
            bus.new_method_call(service::logging, object_path::logging,
                                interface::deleteAll, "DeleteAll");
        auto reply = bus.call(method);
    }
    catch (const SdBusError& e)
    {
        std::cerr << "D-Bus call to delete all event logs failed: " << e.what()
                  << "\n";
        exit(1);
    }
}

/**
 * @brief Display a single PEL
 *
 * @param[in] pel - the PEL to display
 */
void displayPEL(const PEL& pel)
{
    if (pel.valid())
    {
        pel.toJSON(registry);
    }
    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] scrubRegex - SRC regex object
 */
void printPELCount(bool hidden, bool includeInfo,
                   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;
        }
        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 idToDelete;
    std::string scrubFile;
    std::optional<std::regex> scrubRegex;
    bool listPEL = false;
    bool listPELDescOrd = false;
    bool hidden = false;
    bool includeInfo = false;
    bool deleteAll = false;
    bool showPELCount = false;
    bool fullPEL = 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_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_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");

    CLI11_PARSE(app, argc, argv);

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