#pragma once
#include "bcd_time.hpp"
#include "paths.hpp"
#include "pel.hpp"

#include <algorithm>
#include <bitset>
#include <filesystem>
#include <map>

namespace openpower
{
namespace pels
{

/**
 * @class Repository
 *
 * The class handles saving and retrieving PELs on the BMC.
 */
class Repository
{
  public:
    /**
     * @brief Structure of commonly used PEL attributes.
     */
    struct PELAttributes
    {
        std::filesystem::path path;
        size_t sizeOnDisk;
        uint8_t creator;
        uint8_t subsystem;
        uint8_t severity;
        std::bitset<16> actionFlags;
        TransmissionState hostState;
        TransmissionState hmcState;
        uint32_t plid;
        bool deconfig;
        bool guard;
        uint64_t creationTime;

        PELAttributes() = delete;

        PELAttributes(const std::filesystem::path& p, size_t size,
                      uint8_t creator, uint8_t subsystem, uint8_t sev,
                      uint16_t flags, TransmissionState hostState,
                      TransmissionState hmcState, uint32_t plid, bool deconfig,
                      bool guard, uint64_t creationTime) :
            path(p), sizeOnDisk(size), creator(creator), subsystem(subsystem),
            severity(sev), actionFlags(flags), hostState(hostState),
            hmcState(hmcState), plid(plid), deconfig(deconfig), guard(guard),
            creationTime(creationTime)
        {}
    };

    /**
     * @brief A structure that holds both the PEL and corresponding
     *        OpenBMC IDs.
     * Used for correlating the IDs with their data files for quick
     * lookup.  To find a PEL based on just one of the IDs, just use
     * the constructor that takes that ID.
     */
    struct LogID
    {
        struct Pel
        {
            uint32_t id;
            explicit Pel(uint32_t i) : id(i) {}
        };
        struct Obmc
        {
            uint32_t id;
            explicit Obmc(uint32_t i) : id(i) {}
        };

        Pel pelID;

        Obmc obmcID;

        LogID(Pel pel, Obmc obmc) : pelID(pel), obmcID(obmc) {}

        explicit LogID(Pel id) : pelID(id), obmcID(0) {}

        explicit LogID(Obmc id) : pelID(0), obmcID(id) {}

        LogID() = delete;

        /**
         * @brief A == operator that will match on either ID
         *        being equal if the other is zero, so that
         *        one can look up a PEL with just one of the IDs.
         */
        bool operator==(const LogID& id) const
        {
            if (id.pelID.id != 0)
            {
                return id.pelID.id == pelID.id;
            }
            if (id.obmcID.id != 0)
            {
                return id.obmcID.id == obmcID.id;
            }
            return false;
        }

        bool operator<(const LogID& id) const
        {
            return pelID.id < id.pelID.id;
        }
    };

    using AttributesReference =
        std::reference_wrapper<const std::pair<const LogID, PELAttributes>>;

    /**
     * @brief A structure for keeping a breakdown of the sizes of PELs
     *        of different types in the repository.
     */
    struct SizeStats
    {
        uint64_t total;
        uint64_t bmc;
        uint64_t nonBMC;
        uint64_t bmcServiceable;
        uint64_t bmcInfo;
        uint64_t nonBMCServiceable;
        uint64_t nonBMCInfo;

        SizeStats() :
            total(0), bmc(0), nonBMC(0), bmcServiceable(0), bmcInfo(0),
            nonBMCServiceable(0), nonBMCInfo(0)
        {}
    };

    Repository() = delete;
    ~Repository() = default;
    Repository(const Repository&) = default;
    Repository& operator=(const Repository&) = delete;
    Repository(Repository&&) = delete;
    Repository& operator=(Repository&&) = delete;

    /**
     * @brief Constructor
     *
     * @param[in] basePath - the base filesystem path for the repository
     */
    explicit Repository(const std::filesystem::path& basePath) :
        Repository(basePath, getPELRepoSize(), getMaxNumPELs())
    {}

    /**
     * @brief Constructor that takes the repository size
     *
     * @param[in] basePath - the base filesystem path for the repository
     * @param[in] repoSize - The maximum amount of space to use for PELs,
     *                       in bytes
     * @param[in] maxNumPELs - The maximum number of PELs to allow
     */
    Repository(const std::filesystem::path& basePath, size_t repoSize,
               size_t maxNumPELs);

    /**
     * @brief Adds a PEL to the repository
     *
     * Throws File.Error.Open or File.Error.Write exceptions on failure
     *
     * @param[in] pel - the PEL to add
     */
    void add(std::unique_ptr<PEL>& pel);

    /**
     * @brief Removes a PEL from the repository
     *
     * Note that the returned LogID is the fully filled in LogID, i.e.
     * it has both the PEL and OpenBMC IDs, unlike the passed in LogID
     * which can just have one or the other.
     *
     * @param[in] id - the ID (either the pel ID, OBMC ID, or both) to remove
     *
     * @return std::optional<LogID> - The LogID of the removed PEL
     */
    std::optional<LogID> remove(const LogID& id);

    /**
     * @brief Generates the filename to use for the PEL ID and BCDTime.
     *
     * @param[in] pelID - the PEL ID
     * @param[in] time - the BCD time
     *
     * @return string - A filename string of <BCD_time>_<pelID>
     */
    static std::string getPELFilename(uint32_t pelID, const BCDTime& time);

    /**
     * @brief Returns true if the PEL with the specified ID is in the repo.
     *
     * @param[in] id - the ID (either the pel ID, OBMC ID, or both)
     * @return bool - true if that PEL is present
     */
    inline bool hasPEL(const LogID& id)
    {
        return findPEL(id) != _pelAttributes.end();
    }

    /**
     * @brief Returns the PEL data based on its ID.
     *
     * If the data can't be found for that ID, then the optional object
     * will be empty.
     *
     * @param[in] id - the LogID to get the PEL for, which can be either a
     *                 PEL ID or OpenBMC log ID.
     * @return std::optional<std::vector<uint8_t>> - the PEL data
     */
    std::optional<std::vector<uint8_t>> getPELData(const LogID& id);

    /**
     * @brief Get a file descriptor to the PEL data
     *
     * @param[in] id - The ID to get the FD for
     *
     * @return std::optional<sdbusplus::message::unix_fd> -
     *         The FD, or an empty optional object.
     */
    std::optional<sdbusplus::message::unix_fd> getPELFD(const LogID& id);

    using ForEachFunc = std::function<bool(const PEL&)>;

    /**
     * @brief Run a user defined function on every PEL in the repository.
     *
     * ForEachFunc takes a const PEL reference, and should return
     * true to stop iterating and return out of for_each.
     *
     * For example, to save up to 100 IDs in the repo into a vector:
     *
     *     std::vector<uint32_t> ids;
     *     ForEachFunc f = [&ids](const PEL& pel) {
     *         ids.push_back(pel.id());
     *         return ids.size() == 100 ? true : false;
     *     };
     *
     * @param[in] func - The function to run.
     */
    void for_each(ForEachFunc func) const;

    using AddCallback = std::function<void(const PEL&)>;

    /**
     * @brief Subscribe to PELs being added to the repository.
     *
     * Every time a PEL is added to the repository, the provided
     * function will be called with the new PEL as the argument.
     *
     * The function must be of type void(const PEL&).
     *
     * @param[in] name - The subscription name
     * @param[in] func - The callback function
     */
    void subscribeToAdds(const std::string& name, AddCallback func)
    {
        _addSubscriptions.emplace(name, func);
    }

    /**
     * @brief Unsubscribe from new PELs.
     *
     * @param[in] name - The subscription name
     */
    void unsubscribeFromAdds(const std::string& name)
    {
        _addSubscriptions.erase(name);
    }

    using DeleteCallback = std::function<void(uint32_t)>;

    /**
     * @brief Subscribe to PELs being deleted from the repository.
     *
     * Every time a PEL is deleted from the repository, the provided
     * function will be called with the PEL ID as the argument.
     *
     * The function must be of type void(const uint32_t).
     *
     * @param[in] name - The subscription name
     * @param[in] func - The callback function
     */
    void subscribeToDeletes(const std::string& name, DeleteCallback func)
    {
        _deleteSubscriptions.emplace(name, func);
    }

    /**
     * @brief Unsubscribe from deleted PELs.
     *
     * @param[in] name - The subscription name
     */
    void unsubscribeFromDeletes(const std::string& name)
    {
        _deleteSubscriptions.erase(name);
    }

    /**
     * @brief Get the PEL attributes for a PEL
     *
     * @param[in] id - The ID to find the attributes for
     *
     * @return The attributes or an empty optional if not found
     */
    std::optional<std::reference_wrapper<const PELAttributes>> getPELAttributes(
        const LogID& id) const;

    /**
     * @brief Returns the attributes map so that others can traverse PELs.
     *
     * @return - A const reference to the attributes map.
     */
    const std::map<LogID, PELAttributes>& getAttributesMap() const
    {
        return _pelAttributes;
    }

    /**
     * @brief Sets the host transmission state on a PEL file
     *
     * Writes the host transmission state field in the User Header
     * section in the PEL data specified by the ID.
     *
     * @param[in] pelID - The PEL ID
     * @param[in] state - The state to write
     */
    void setPELHostTransState(uint32_t pelID, TransmissionState state);

    /**
     * @brief Sets the HMC transmission state on a PEL file
     *
     * Writes the HMC transmission state field in the User Header
     * section in the PEL data specified by the ID.
     *
     * @param[in] pelID - The PEL ID
     * @param[in] state - The state to write
     */
    void setPELHMCTransState(uint32_t pelID, TransmissionState state);

    /**
     * @brief Returns the size stats structure
     *
     * @return const SizeStats& - The stats structure
     */
    const SizeStats& getSizeStats() const
    {
        return _sizes;
    }

    /**
     * @brief Says if the PEL is considered serviceable (not just
     *        informational) as determined by its severity.
     *
     * @param[in] pel - The PELAttributes entry for the PEL
     * @return bool - If serviceable or not
     */
    static bool isServiceableSev(const PELAttributes& pel);

    /**
     * @brief Returns true if the total amount of disk space occupied
     *        by the PELs in the repo is over 95% of the maximum
     *        size, or if there are over the maximum number of
     *        PELs allowed.
     *
     * @return bool - true if repo is > 95% full or too many PELs
     */
    bool sizeWarning();

    /**
     * @brief Deletes PELs to bring the repository size down
     *        to at most 90% full by placing PELs into 4 different
     *        catogories and then removing PELs until those catogories
     *        only take up certain percentages of the allowed space.
     *
     * This does not delete the corresponding OpenBMC event logs, which
     * is why those IDs are returned, so they can be deleted later.
     *
     * The categories and their rules are:
     *  1) Informational BMC PELs cannot take up more than 15% of
     *     the allocated space.
     *  2) Non-informational BMC PELs cannot take up more than 30%
     *     of the allocated space.
     *  3) Informational non-BMC PELs cannot take up more than 15% of
     *     the allocated space.
     *  4) Non-informational non-BMC PELs cannot take up more than 30%
     *     of the allocated space.
     *
     *  While removing PELs in a category, 4 passes will be made, with
     *  PELs being removed oldest first during each pass.
     *
     *   Pass 1: only delete HMC acked PELs
     *   Pass 2: only delete OS acked PELs
     *   Pass 3: only delete PHYP sent PELs
     *   Pass 4: delete all PELs
     *
     * @param[in] ids - The OpenBMC event log Ids with hardware isolation entry.
     *
     * @return std::vector<uint32_t> - The OpenBMC event log IDs of
     *                                 the PELs that were deleted.
     */
    std::vector<uint32_t> prune(const std::vector<uint32_t>& idsWithHwIsoEntry);

    /**
     * @brief Returns the path to the directory where the PEL
     *        files are stored.
     *
     * @return std::filesystem::path - The directory path
     */
    const std::filesystem::path& repoPath() const
    {
        return _logPath;
    }

    /**
     * @brief Returns the ID of the most recently added PEL.
     *
     * @return uint32_t - The PEL ID
     */
    uint32_t lastPelID() const
    {
        return _lastPelID;
    }

    /**
     * @brief Get the LogID based on the given ObmcLogId or PelId.
     *
     * @param[in] id - The ID to find the LogID.
     *
     * @return The LogID or an empty optional if not found.
     *
     * @note The returned LogID is the fully filled in LogID, i.e.
     * it has both the PEL and OpenBMC Log IDs, unlike the passed in LogID
     * which can just have one or the other.
     */
    std::optional<LogID> getLogID(const LogID& id) const
    {
        if (auto logID = findPEL(id); logID != _pelAttributes.end())
        {
            return logID->first;
        }
        return std::nullopt;
    }

    /**
     * @brief Save the PEL to archive folder
     *
     * @param[in] pel - The PEL data
     */
    void archivePEL(const PEL& pel);

    using PELUpdateFunc = std::function<bool(PEL&)>;

    /**
     * @brief Lets a function modify a PEL and saves the results
     *
     * Runs updateFunc (a bool(PEL&) function) on the PEL data
     * on the file specified, and writes the results back to the file
     * if the function returned true.
     *
     * @param[in] path - The file path to use
     * @param[in] updateFunc - The function to run to update the PEL.
     *
     * @return bool - If the PEL was updated or not.
     */
    bool updatePEL(const std::filesystem::path& path, PELUpdateFunc updateFunc);

  private:
    /**
     * @brief Finds an entry in the _pelAttributes map.
     *
     * @param[in] id - the ID (either the pel ID, OBMC ID, or both)
     *
     * @return an iterator to the entry
     */
    std::map<LogID, PELAttributes>::const_iterator findPEL(
        const LogID& id) const
    {
        return std::find_if(_pelAttributes.begin(), _pelAttributes.end(),
                            [&id](const auto& a) { return a.first == id; });
    }

    /**
     * @brief Call any subscribed functions for new PELs
     *
     * @param[in] pel - The new PEL
     */
    void processAddCallbacks(const PEL& pel) const;

    /**
     * @brief Call any subscribed functions for deleted PELs
     *
     * @param[in] id - The ID of the deleted PEL
     */
    void processDeleteCallbacks(uint32_t id) const;

    /**
     * @brief Restores the _pelAttributes map on startup based on the existing
     *        PEL data files.
     */
    void restore();

    /**
     * @brief Stores a PEL object in the filesystem.
     *
     * @param[in] pel - The PEL to write
     * @param[in] path - The file to write to
     *
     * Throws exceptions on failures.
     */
    void write(const PEL& pel, const std::filesystem::path& path);

    /**
     * @brief Updates the repository statistics after a PEL is
     *        added or removed.
     *
     * @param[in] pel - The PELAttributes entry for the PEL
     * @param[in] pelAdded - true if the PEL was added, false if removed
     */
    void updateRepoStats(const PELAttributes& pel, bool pelAdded);

    enum class SortOrder
    {
        ascending,
        descending
    };

    /**
     * @brief Returns a vector of all the _pelAttributes entries sorted
     *        as specified
     *
     * @param[in] order - If the PELs should be returned in ascending
     *                    (oldest first) or descending order.
     *
     * @return std::vector<AttributesReference> - The sorted vector of
     *         references to the pair<LogID, PELAttributes> entries of
     *         _pelAttributes.
     */
    std::vector<AttributesReference> getAllPELAttributes(SortOrder order) const;

    using IsOverLimitFunc = std::function<bool()>;
    using IsPELTypeFunc = std::function<bool(const PELAttributes&)>;

    /**
     * @brief Makes 4 passes on the PELs that meet the IsPELTypeFunc
     *        criteria removing PELs until IsOverLimitFunc returns false.
     *
     *   Pass 1: only delete HMC acked PELs
     *   Pass 2: only delete Os acked PELs
     *   Pass 3: only delete PHYP sent PELs
     *   Pass 4: delete all PELs
     *
     * @param[in] isOverLimit - The bool(void) function that should
     *                          return true if PELs still need to be
     *                           removed.
     * @param[in] isPELType - The bool(const PELAttributes&) function
     *                         used to select the PELs to operate on.
     * @param[in] ids - The OpenBMC event log Ids with hardware isolation
     *                   entry.
     *
     * @param[out] removedBMCLogIDs - The OpenBMC event log IDs of the
     *                                removed PELs.
     */
    void removePELs(const IsOverLimitFunc& isOverLimit,
                    const IsPELTypeFunc& isPELType,
                    const std::vector<uint32_t>& idsWithHwIsoEntry,
                    std::vector<uint32_t>& removedBMCLogIDs);
    /**
     * @brief The filesystem path to the PEL logs.
     */
    const std::filesystem::path _logPath;

    /**
     * @brief A map of the PEL/OBMC IDs to PEL attributes.
     */
    std::map<LogID, PELAttributes> _pelAttributes;

    /**
     * @brief Subcriptions for new PELs.
     */
    std::map<std::string, AddCallback> _addSubscriptions;

    /**
     * @brief Subscriptions for deleted PELs.
     */
    std::map<std::string, DeleteCallback> _deleteSubscriptions;

    /**
     * @brief The maximum amount of space that the PELs in the
     *        repository can occupy.
     */
    const uint64_t _maxRepoSize;

    /**
     * @brief The maximum number of PELs to allow in the repo
     *        before pruning.
     */
    const size_t _maxNumPELs;

    /**
     * @brief Statistics on the sizes of the stored PELs.
     */
    SizeStats _sizes;

    /**
     * @brief The ID of the most recently added PEL.
     */
    uint32_t _lastPelID = 0;

    /**
     * @brief The filesystem path to the archive PEL logs.
     */
    const std::filesystem::path _archivePath;

    /**
     * @brief The size of archive folder.
     */
    uint64_t _archiveSize = 0;
};

} // namespace pels
} // namespace openpower
