#pragma once

#include "config.h"

#include "file.hpp"
#include "occ_errors.hpp"

#include <systemd/sd-journal.h>

#include <nlohmann/json.hpp>
#include <xyz/openbmc_project/Logging/Create/server.hpp>

using FFDCFormat =
    sdbusplus::xyz::openbmc_project::Logging::server::Create::FFDCFormat;
using FFDCFiles = std::vector<
    std::tuple<FFDCFormat, uint8_t, uint8_t, sdbusplus::message::unix_fd>>;

namespace open_power
{
namespace occ
{

/** @class FFDCFile
 *  @brief Represents a single file that will get opened when created and
 *         deleted when the object is destructed
 */
class FFDCFile
{
  public:
    FFDCFile() = delete;
    FFDCFile(const FFDCFile&) = delete;
    FFDCFile& operator=(const FFDCFile&) = delete;
    FFDCFile(FFDCFile&&) = delete;
    FFDCFile& operator=(FFDCFile&&) = delete;

    /**
     * @brief Constructor
     *
     * Opens the file and saves the descriptor
     *
     * @param[in] name - The filename
     */
    explicit FFDCFile(const std::filesystem::path& name);

    /**
     * @brief Destructor - Deletes the file
     */
    ~FFDCFile()
    {
        std::filesystem::remove(_name);
    }

    /**
     * @brief Returns the file descriptor
     *
     * @return int - The descriptor
     */
    int fd()
    {
        return _fd();
    }

  private:
    /**
     * @brief The file descriptor holder
     */
    FileDescriptor _fd;

    /**
     * @brief The filename
     */
    const std::filesystem::path _name;
};

/** @class FFDC
 *  @brief Monitors for SBE FFDC availability
 */
class FFDC : public Error
{
  public:
    FFDC() = delete;
    FFDC(const FFDC&) = delete;
    FFDC& operator=(const FFDC&) = delete;
    FFDC(FFDC&&) = default;
    FFDC& operator=(FFDC&&) = default;

    /** @brief Constructs the FFDC object
     *
     *  @param[in] event    - reference to sd_event unique_ptr
     *  @param[in] file     - File used by driver to communicate FFDC data
     *  @param[in] instance - OCC instance number
     */
    FFDC(EventPtr& event, const fs::path& file, unsigned int instance) :
        Error(event, file, nullptr), instance(instance)
    {
        // Nothing to do here.
    }

    ~FFDC()
    {
        for (auto&& it : temporaryFiles)
        {
            close(it.second);
            fs::remove(it.first);
        }
    }

    /** @brief Helper function to create a PEL with the OpenPower DBus
     *         interface
     *
     * @param[in] path - the DBus error path
     * @param[in] src6 - the SBE error SRC6 word
     * @param[in] msg - the error message
     * @param[in] fd - the file descriptor for any FFDC
     */
    static uint32_t createPEL(const char* path, uint32_t src6, const char* msg,
                              int fd = -1);

    /** @brief Helper function to create a PEL for the OCC reset with the
     * OpenPower DBus interface
     *
     * @param[in] instance - the OCC instance id
     * @param[in] path - the DBus error path
     * @param[in] err - the error return code
     * @param[in] callout - the PEL callout path
     */
    static void createOCCResetPEL(unsigned int instance, const char* path,
                                  int err, const char* callout);

    /**
     * @brief Create a file containing the latest journal traces for the
     *        specified executable and add it to the file list.
     *
     * @param[in] fileList     - where to add the new file
     * @param[in] executable   - name of app to collect
     * @param[in] lines        - number of journal lines to save
     *
     * @return std::unique_ptr<FFDCFile> - The file object
     */
    static std::unique_ptr<FFDCFile> addJournalEntries(
        FFDCFiles& fileList, const std::string& executable, unsigned int lines);

  private:
    /** @brief OCC instance number. Ex, 0,1, etc */
    unsigned int instance;

    /** @brief Stores the temporary files and file descriptors
     *         in usage. They will be cleaned up when the class
     *         is destroyed (when the application exits).
     */
    std::vector<std::pair<fs::path, int>> temporaryFiles;

    /** @brief When the error event is received, analyzes it
     *         and makes a callback to error handler if the
     *         content denotes an error condition
     */
    void analyzeEvent() override;

    /**
     * @brief Returns an FFDCFile containing the JSON data
     *
     * @param[in] ffdcData - The JSON data to write to a file
     *
     * @return std::unique_ptr<FFDCFile> - The file object
     */
    static std::unique_ptr<FFDCFile>
        makeJsonFFDCFile(const nlohmann::json& ffdcData);

    /**
     * @brief Returns a JSON structure containing the previous N journal
     * entries.
     *
     * @param[in] numLines   - Number of lines of journal to retrieve
     * @param[in] executable - name of app to collect for
     *
     * @return JSON object that was created
     */
    static nlohmann::json getJournalEntries(int numLines,
                                            std::string executable);

    /**
     * @brief Gets the realtime (wallclock) timestamp for the current journal
     * entry.
     *
     * @param journal current journal entry
     * @return timestamp as a date/time string
     */
    static std::string getTimeStamp(sd_journal* journal);

    /**
     * @brief Gets the value of the specified field for the current journal
     * entry.
     *
     * Returns an empty string if the current journal entry does not have the
     * specified field.
     *
     * @param journal current journal entry
     * @param field journal field name
     * @return field value
     */
    static std::string getFieldValue(sd_journal* journal,
                                     const std::string& field);
};

/**
 * @class JournalCloser
 *  @brief Automatically closes the journal when the object goes out of scope.
 */
class JournalCloser
{
  public:
    // Specify which compiler-generated methods we want
    JournalCloser() = delete;
    JournalCloser(const JournalCloser&) = delete;
    JournalCloser(JournalCloser&&) = delete;
    JournalCloser& operator=(const JournalCloser&) = delete;
    JournalCloser& operator=(JournalCloser&&) = delete;

    JournalCloser(sd_journal* journal) : journal{journal} {}

    ~JournalCloser()
    {
        sd_journal_close(journal);
    }

  private:
    sd_journal* journal{nullptr};
};

} // namespace occ
} // namespace open_power
