#pragma once

#include "interfaces/json_storage.hpp"
#include "interfaces/report.hpp"
#include "interfaces/report_factory.hpp"
#include "interfaces/report_manager.hpp"
#include "report.hpp"

#include <systemd/sd-bus-protocol.h>

#include <sdbusplus/asio/object_server.hpp>

#include <chrono>
#include <memory>
#include <string>
#include <vector>

class ReportManager : public interfaces::ReportManager
{
  public:
    ReportManager(
        std::unique_ptr<interfaces::ReportFactory> reportFactory,
        std::unique_ptr<interfaces::JsonStorage> reportStorage,
        const std::shared_ptr<sdbusplus::asio::object_server>& objServer);
    ~ReportManager() = default;

    ReportManager(const ReportManager&) = delete;
    ReportManager(ReportManager&&) = delete;
    ReportManager& operator=(const ReportManager&) = delete;
    ReportManager& operator=(ReportManager&&) = delete;

    void removeReport(const interfaces::Report* report) override;
    void updateReport(const std::string& id) override;

  private:
    std::unique_ptr<interfaces::ReportFactory> reportFactory;
    std::unique_ptr<interfaces::JsonStorage> reportStorage;
    std::shared_ptr<sdbusplus::asio::object_server> objServer;
    std::unique_ptr<sdbusplus::asio::dbus_interface> reportManagerIface;
    std::vector<std::unique_ptr<interfaces::Report>> reports;

    void verifyReportIdLength(const std::string& reportName);
    void verifyAddReport(
        const std::string& reportId, const std::string& reportName,
        const ReportingType reportingType, Milliseconds interval,
        const ReportUpdates reportUpdates,
        const std::vector<LabeledMetricParameters>& readingParams);
    interfaces::Report& addReport(
        boost::asio::yield_context& yield, const std::string& reportId,
        const std::string& reportName, const ReportingType reportingType,
        const std::vector<ReportAction>& reportActions, Milliseconds interval,
        const uint64_t appendLimit, const ReportUpdates reportUpdates,
        ReadingParameters metricParams, const bool enabled);
    interfaces::Report& addReport(
        const std::string& reportId, const std::string& reportName,
        const ReportingType reportingType,
        const std::vector<ReportAction>& reportActions, Milliseconds interval,
        const uint64_t appendLimit, const ReportUpdates reportUpdates,
        std::vector<LabeledMetricParameters> metricParams, const bool enabled);
    void loadFromPersistent();

  public:
    static constexpr size_t maxReports{TELEMETRY_MAX_REPORTS};
    static constexpr size_t maxReadingParams{TELEMETRY_MAX_READING_PARAMS};
    static constexpr size_t maxReportIdLength{
        TELEMETRY_MAX_DBUS_PATH_LENGTH -
        std::string_view(Report::reportDir).length()};
    static constexpr Milliseconds minInterval{TELEMETRY_MIN_INTERVAL};
    static constexpr const char* reportManagerIfaceName =
        "xyz.openbmc_project.Telemetry.ReportManager";
    static constexpr const char* reportManagerPath =
        "/xyz/openbmc_project/Telemetry/Reports";
    static constexpr std::array<ReportUpdates, 3> supportedReportUpdates = {
        ReportUpdates::overwrite, ReportUpdates::appendStopsWhenFull,
        ReportUpdates::appendWrapsWhenFull};

    static void verifyReportUpdates(const ReportUpdates reportUpdates);
};
