#pragma once

#include "config.h"

#include "data_interface.hpp"
#include "event_logger.hpp"
#include "host_notifier.hpp"
#include "journal.hpp"
#include "log_manager.hpp"
#include "paths.hpp"
#include "pel.hpp"
#include "registry.hpp"
#include "repository.hpp"

#include <org/open_power/Logging/PEL/Entry/server.hpp>
#include <org/open_power/Logging/PEL/server.hpp>
#include <sdbusplus/server.hpp>
#include <sdeventplus/event.hpp>
#include <sdeventplus/source/event.hpp>
#include <xyz/openbmc_project/Logging/Create/server.hpp>

namespace openpower
{
namespace pels
{

using PELInterface = sdbusplus::server::object_t<
    sdbusplus::org::open_power::Logging::server::PEL>;

/**
 * @brief PEL manager object
 */
class Manager : public PELInterface
{
  public:
    Manager() = delete;
    Manager(const Manager&) = default;
    Manager& operator=(const Manager&) = default;
    Manager(Manager&&) = default;
    Manager& operator=(Manager&&) = default;

    /**
     * @brief constructor
     *
     * @param[in] logManager - internal::Manager object
     * @param[in] dataIface - The data interface object
     * @param[in] creatorFunc - The function that EventLogger will
     *                          use for creating event logs
     */
    Manager(phosphor::logging::internal::Manager& logManager,
            std::unique_ptr<DataInterfaceBase> dataIface,
            EventLogger::LogFunction creatorFunc,
            std::unique_ptr<JournalBase> journal) :
        PELInterface(logManager.getBus(), OBJ_LOGGING),
        _logManager(logManager), _eventLogger(std::move(creatorFunc)),
        _repo(getPELRepoPath()),
        _registry(getPELReadOnlyDataPath() / message::registryFileName),
        _event(sdeventplus::Event::get_default()),
        _dataIface(std::move(dataIface)), _journal(std::move(journal))
    {
        for (const auto& entry : _logManager.entries)
        {
            setEntryPath(entry.first);
            setServiceProviderNotifyFlag(entry.first);
            // Create PELEntry interface and setup properties with their values
            createPELEntry(entry.first, true);
        }

        setupPELDeleteWatch();

        _dataIface->subscribeToFruPresent(
            "Manager",
            std::bind(&Manager::hardwarePresent, this, std::placeholders::_1));
    }

    /**
     * @brief constructor that enables host notification
     *
     * @param[in] logManager - internal::Manager object
     * @param[in] dataIface - The data interface object
     * @param[in] creatorFunc - The function that EventLogger will
     *                          use for creating event logs
     * @param[in] hostIface - The hostInterface object
     */
    Manager(phosphor::logging::internal::Manager& logManager,
            std::unique_ptr<DataInterfaceBase> dataIface,
            EventLogger::LogFunction creatorFunc,
            std::unique_ptr<JournalBase> journal,
            std::unique_ptr<HostInterface> hostIface) :
        Manager(logManager, std::move(dataIface), std::move(creatorFunc),
                std::move(journal))
    {
        _hostNotifier = std::make_unique<HostNotifier>(
            _repo, *(_dataIface.get()), std::move(hostIface));
    }

    /**
     * @brief Destructor
     */
    ~Manager();

    /**
     * @brief Creates a PEL based on the OpenBMC event log contents.  If
     *        a PEL was passed in via the RAWPEL specifier in the
     *        additionalData parameter, use that instead.
     *
     * @param[in] message - the event log message property
     * @param[in] obmcLogID - the corresponding OpenBMC event log id
     * @param[in] timestamp - the Timestamp property
     * @param[in] severity - the event log severity
     * @param[in] additionalData - the AdditionalData property
     * @param[in] associations - the Associations property
     * @param[in] ffdc - A vector of FFDC file information
     */
    void create(const std::string& message, uint32_t obmcLogID,
                uint64_t timestamp, phosphor::logging::Entry::Level severity,
                const std::vector<std::string>& additionalData,
                const std::vector<std::string>& associations,
                const phosphor::logging::FFDCEntries& ffdc =
                    phosphor::logging::FFDCEntries{});

    /**
     * @brief Erase a PEL based on its OpenBMC event log ID
     *
     * @param[in] obmcLogID - the corresponding OpenBMC event log id
     */
    void erase(uint32_t obmcLogID);

    /** @brief Says if an OpenBMC event log may not be manually deleted at this
     *         time because its corresponding PEL cannot be.
     *
     * There are PEL retention policies that can prohibit the manual deletion
     * of PELs (and therefore OpenBMC event logs).
     *
     * @param[in] obmcLogID - the OpenBMC event log ID
     * @return bool - true if prohibited
     */
    bool isDeleteProhibited(uint32_t obmcLogID);

    /**
     * @brief Return a file descriptor to the raw PEL data
     *
     * Throws InvalidArgument if the PEL ID isn't found,
     * and InternalFailure if anything else fails.
     *
     * @param[in] pelID - The PEL ID to get the data for
     *
     * @return unix_fd - File descriptor to the file that contains the PEL
     */
    sdbusplus::message::unix_fd getPEL(uint32_t pelID) override;

    /**
     * @brief Returns data for the PEL corresponding to an OpenBMC
     *        event log.
     *
     * @param[in] obmcLogID - The OpenBMC event log ID
     *
     * @return vector<uint8_t> - The raw PEL data
     */
    std::vector<uint8_t> getPELFromOBMCID(uint32_t obmcLogID) override;

    /**
     * @brief The D-Bus method called when a host successfully processes
     *        a PEL.
     *
     * This D-Bus method is called from the PLDM daemon when they get an
     * 'Ack PEL' PLDM message from the host, which indicates the host
     * firmware successfully sent it to the OS and this code doesn't need
     * to send it to the host again.
     *
     * @param[in] pelID - The PEL ID
     */
    void hostAck(uint32_t pelID) override;

    /**
     * @brief D-Bus method called when the host rejects a PEL.
     *
     * This D-Bus method is called from the PLDM daemon when they get an
     * 'Ack PEL' PLDM message from the host with a payload that says
     * something when wrong.
     *
     * The choices are either:
     *  * Host Full - The host's staging area is full - try again later
     *  * Malrformed PEL - The host received an invalid PEL
     *
     * @param[in] pelID - The PEL ID
     * @param[in] reason - One of the above two reasons
     */
    void hostReject(uint32_t pelID, RejectionReason reason) override;

    /**
     * @brief D-Bus method to create a PEL/OpenBMC event log and
     *        return the created OpenBMC and PEL log IDs.
     *
     * The same as the CreateWithFFDCFiles method on the
     * xyz.openbmc_project.Logging.Create interface, except for
     * the return values.
     *
     * @param[in] message - The event log message property
     * @param[in] severity - The event log severity
     * @param[in] additionalData - The AdditionalData property
     * @param[in] ffdc - A vector of FFDC file information
     */
    std::tuple<uint32_t, uint32_t> createPELWithFFDCFiles(
        std::string message, phosphor::logging::Entry::Level severity,
        std::map<std::string, std::string> additionalData,
        std::vector<std::tuple<sdbusplus::xyz::openbmc_project::Logging::
                                   server::Create::FFDCFormat,
                               uint8_t, uint8_t, sdbusplus::message::unix_fd>>
            fFDC) override;

    /**
     * @brief D-Bus method to return the PEL in JSON format
     *
     * @param[in] obmcLogID - The OpenBMC entry log ID
     *
     * @return std::string - The fully parsed PEL in JSON
     */
    std::string getPELJSON(uint32_t obmcLogID) override;

    /**
     * @brief Converts the ESEL field in an OpenBMC event log to a
     *        vector of uint8_ts that just contains the PEL data.
     *
     * That data string looks like: "50 48 00 ab ..."
     *
     * Throws an exception on any failures.
     *
     * @param[in] esel - The ESEL string
     *
     * @return std::vector<uint8_t> - The contained PEL data
     */
    static std::vector<uint8_t> eselToRawData(const std::string& esel);

    /**
     * @brief Generate resolution string from the PEL
     *
     * @param[in] pel - The PEL to use
     */
    std::string getResolution(const openpower::pels::PEL& pel) const;

    /**
     * @brief Generate event ID from the PEL
     *
     * @param[in] pel - The PEL to use
     */
    std::string getEventId(const openpower::pels::PEL& pel) const;

    /** @brief Implementation for GetPELIdFromBMCLogId
     *
     *  Returns the PEL Id (aka Entry ID (EID)) based on the given
     *  BMC event log id.
     *
     *  @param[in] bmcLogId - The BMC event log id of the PEL to retrieve
     *                        the PEL id.
     *
     *  @return uint32_t - The Id of the PEL.
     *                     Throw "InvalidArgument" if not found.
     */
    uint32_t getPELIdFromBMCLogId(uint32_t bmcLogId) override;

    /** @brief Implementation for GetBMCLogIdFromPELId
     *
     *  Returns the BMC event log id based on the given PEL id
     *  (aka Entry ID (EID)).
     *
     *  @param[in] pelId - The PEL id to retrieve the BMC event log id.
     *
     *  @return uint32_t - The BMC event log id of the PEL.
     *                     Throw "InvalidArgument" if not found.
     */
    uint32_t getBMCLogIdFromPELId(uint32_t pelId) override;

    /**
     * @brief Update boot progress SRC based on severity 0x51, critical error
     *
     * @param[in] pel - The PEL to use
     */
    void updateProgressSRC(std::unique_ptr<openpower::pels::PEL>& pel) const;

    /**
     * @brief Converts unprintable characters from the passed
     *        in string to spaces so they won't crash D-Bus when
     *        used as a property value.
     *
     * @param[in] field - The field to fix
     *
     * @return std::string - The string without non printable characters.
     */
    static std::string sanitizeFieldForDBus(std::string field);

  private:
    /**
     * @brief Adds a received raw PEL to the PEL repository
     *
     * @param[in] rawPelPath - The path to the file that contains the
     *                         raw PEL.
     * @param[in] obmcLogID - the corresponding OpenBMC event log id
     */
    void addRawPEL(const std::string& rawPelPath, uint32_t obmcLogID);

    /**
     * @brief Creates a PEL based on the OpenBMC event log contents.
     *
     * @param[in] message - The event log message property
     * @param[in] obmcLogID - the corresponding OpenBMC event log id
     * @param[in] timestamp - The timestamp property
     * @param[in] severity - The event log severity
     * @param[in] additionalData - The AdditionalData property
     * @param[in] associations - The associations property
     * @param[in] ffdc - A vector of FFDC file information
     */
    void createPEL(const std::string& message, uint32_t obmcLogID,
                   uint64_t timestamp, phosphor::logging::Entry::Level severity,
                   const std::vector<std::string>& additionalData,
                   const std::vector<std::string>& associations,
                   const phosphor::logging::FFDCEntries& ffdc);

    /**
     * @brief Schedules a close of the file descriptor to occur from
     *        the event loop.
     *
     * Uses sd_event_add_defer
     *
     * @param[in] fd - The file descriptor to close
     */
    void scheduleFDClose(int fd);

    /**
     * @brief Closes the file descriptor passed in.
     *
     * This is called from the event loop to close FDs returned
     * from getPEL().
     *
     * @param[in] fd - The file descriptor to close
     * @param[in] source - The event source object used
     */
    void closeFD(int fd, sdeventplus::source::EventBase& source);

    /**
     * @brief Adds a PEL to the repository given its data
     *
     * @param[in] pelData - The PEL to add as a vector of uint8_ts
     * @param[in] obmcLogID - the OpenBMC event log ID
     */
    void addPEL(std::vector<uint8_t>& pelData, uint32_t obmcLogID);

    /**
     * @brief Adds the PEL stored in the ESEL field of the AdditionalData
     *        property of an OpenBMC event log to the repository.
     *
     * @param[in] esel - The ESEL AdditionalData contents
     * @param[in] obmcLogID - The OpenBMC event log ID
     */
    void addESELPEL(const std::string& esel, uint32_t obmcLogID);

    /**
     * @brief Converts the D-Bus FFDC method argument into a data
     *        structure understood by the PEL code.
     *
     * @param[in] ffdc - A vector of FFDC file information
     *
     * @return PelFFDC - The PEL FFDC data structure
     */
    PelFFDC convertToPelFFDC(const phosphor::logging::FFDCEntries& ffdc);

    /**
     * @brief Schedules a PEL repository prune to occur from
     *        the event loop.
     *
     * Uses sd_event_add_defer
     */
    void scheduleRepoPrune();

    /**
     * @brief Prunes old PELs out of the repository to save space.
     *
     * This is called from the event loop.
     *
     * @param[in] source - The event source object used
     */
    void pruneRepo(sdeventplus::source::EventBase& source);

    /**
     * @brief Sets up an inotify watch to watch for deleted PEL
     *        files.  Calls pelFileDeleted() when that occurs.
     */
    void setupPELDeleteWatch();

    /**
     * @brief Called when the inotify watch put on the repository directory
     *        detects a PEL file was deleted.
     *
     * Will tell the Repository class about the deleted PEL, and then tell
     * the log manager class to delete the corresponding OpenBMC event log.
     */
    void pelFileDeleted(sdeventplus::source::IO& io, int fd, uint32_t revents);

    /**
     * @brief Check if the input PEL should cause a quiesce of the system
     *
     * If QuiesceOnHwError is enabled within phosphor-settings and the PEL
     * from the host has a severity which is not SeverityType::nonError or
     * recovered then execute the quiesce and boot block logic.
     *
     * @param[in] pel - The PEL to check
     */
    void checkPelAndQuiesce(std::unique_ptr<openpower::pels::PEL>& pel);

    /**
     * @brief Update eventId D-bus property for this error log
     *
     * Update the eventId property of D-bus with SRC and hexwords from the
     * PEL created
     *
     * @param[in] pel - The PEL to use
     */
    void updateEventId(std::unique_ptr<openpower::pels::PEL>& pel);

    /**
     * @brief Finds and serializes the log entry for the ID passed in.
     * @param[in] obmcLogID - The OpenBMC event log ID
     */
    void serializeLogEntry(uint32_t obmcLogID);

    /**
     * @brief Sets the FilePath of the specified error log entry to the PEL file
     *        path.
     *
     * @param[in] obmcLogID - The OpenBMC entry log ID
     */
    void setEntryPath(uint32_t obmcLogID);

    /**
     * @brief Sets the serviceProviderNotify D-bus property of PEL.
     *
     * @param[in] obmcLogID - The OpenBMC entry log ID
     */
    void setServiceProviderNotifyFlag(uint32_t obmcLogID);

    /**
     * @brief Update resolution D-bus property for this error log
     *
     * Update the resolution property of D-bus with callouts extracted from PEL
     *
     * @param[in] pel - The PEL to use
     *
     * @return bool - false for Repositor::for_each().
     */
    bool updateResolution(const openpower::pels::PEL& pel);

    /**
     * @brief Check if the D-Bus severity property for the event log
     *        needs to be updated based on the final PEL severity,
     *        and update the property accordingly.
     *
     * @param[in] pel - The PEL to operate on.
     */
    void updateDBusSeverity(const openpower::pels::PEL& pel);

    /**
     * @brief Create PELEntry Interface with supported properties
     *
     * Create PELEntry Interface and update all the properties which are
     * supported
     *
     * @param[in] obmcLogID - The OpenBMC entry log ID
     * @param[in] skipIaSignal - If The InterfacesAdded signal should be
     *                           skipped after creating the interfaces.
     */
    void createPELEntry(uint32_t obmcLogID, bool skipIaSignal = false);

    /**
     * @brief Schedules the delete of the OpenBMC event log for when
     *        execution gets back to the event loop (uses sd_event_add_defer).
     *
     * @param[in] obmcLogID - The OpenBMC entry log ID
     */
    void scheduleObmcLogDelete(uint32_t obmcLogID);

    /**
     * @brief SD event callback to delete an OpenBMC event log
     *
     * @param[in] obmcLogID - The OpenBMC entry log ID
     */
    void deleteObmcLog(sdeventplus::source::EventBase&, uint32_t obmcLogID);

    /**
     * @brief Clears the deconfig flag in the PEL if necessary.
     *
     * If the passed in location code is in a callout and it's a PEL with
     * the BMC power/thermal or fans component ID, clear the deconfig flag.
     *
     * @param[in] locationCode - The location code to look for
     * @param[inout] pel - The PEL to check and modify.
     * @return bool - true if the flag was cleared for this PEL
     */
    static bool clearPowerThermalDeconfigFlag(const std::string& locationCode,
                                              openpower::pels::PEL& pel);

    /**
     * @brief Called by DataInterface when the presence of hotpluggable
     *        hardware is detected.
     *
     * Clears the 'Deconfig' flag in any PEL that has the location code
     * of the hardware in a callout.
     *
     * @param[in] locationCode - The location code of the hardware.
     */
    void hardwarePresent(const std::string& locationCode);

    /**
     * @brief Reference to phosphor-logging's Manager class
     */
    phosphor::logging::internal::Manager& _logManager;

    /**
     * @brief Handles creating event logs/PELs from within
     *        the PEL extension code
     */
    EventLogger _eventLogger;

    /**
     * @brief The PEL repository object
     */
    Repository _repo;

    /**
     * @brief The PEL message registry object
     */
    message::Registry _registry;

    /**
     * @brief The Event object this class uses
     */
    sdeventplus::Event _event;

    /**
     * @brief The API the PEL sections use to gather data
     */
    std::unique_ptr<DataInterfaceBase> _dataIface;

    /**
     * @brief Object used to read from the journal
     */
    std::unique_ptr<JournalBase> _journal;

    /**
     * @brief The map used to keep track of PEL entry pointer associated with
     *        event log.
     */
    std::map<std::string,
             std::unique_ptr<
                 sdbusplus::org::open_power::Logging::PEL::server::Entry>>
        _pelEntries;

    /**
     * @brief The HostNotifier object used for telling the
     *        host about new PELs
     */
    std::unique_ptr<HostNotifier> _hostNotifier;

    /**
     * @brief The event source for closing a PEL file descriptor after
     *        it has been returned from the getPEL D-Bus method.
     */
    std::unique_ptr<sdeventplus::source::Defer> _fdCloserEventSource;

    /**
     * @brief The even source for removing old PELs when the repo is
     *        running out of space to make room for new ones.
     */
    std::unique_ptr<sdeventplus::source::Defer> _repoPrunerEventSource;

    /**
     * @brief The event source for deleting an OpenBMC event log.
     *        Used when its corresponding PEL is invalid.
     */
    std::unique_ptr<sdeventplus::source::Defer> _obmcLogDeleteEventSource;

    /**
     * @brief The even source for watching for deleted PEL files.
     */
    std::unique_ptr<sdeventplus::source::IO> _pelFileDeleteEventSource;

    /**
     * @brief The file descriptor returned by inotify_init1() used
     *        for watching for deleted PEL files.
     */
    int _pelFileDeleteFD = -1;

    /**
     * @brief The file descriptor returned by inotify_add_watch().
     */
    int _pelFileDeleteWatchFD = -1;
};

} // namespace pels
} // namespace openpower
