#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&) = default;
    Repository(Repository&&) = default;
    Repository& operator=(Repository&&) = default;

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