#include "report_manager.hpp"

#include "report.hpp"
#include "types/report_types.hpp"
#include "utils/conversion.hpp"
#include "utils/dbus_path_utils.hpp"
#include "utils/make_id_name.hpp"
#include "utils/transform.hpp"

#include <phosphor-logging/log.hpp>
#include <sdbusplus/exception.hpp>
#include <sdbusplus/unpack_properties.hpp>

#include <optional>
#include <stdexcept>
#include <system_error>

ReportManager::ReportManager(
    std::unique_ptr<interfaces::ReportFactory> reportFactoryIn,
    std::unique_ptr<interfaces::JsonStorage> reportStorageIn,
    const std::shared_ptr<sdbusplus::asio::object_server>& objServerIn) :
    reportFactory(std::move(reportFactoryIn)),
    reportStorage(std::move(reportStorageIn)), objServer(objServerIn)
{
    reports.reserve(maxReports);

    loadFromPersistent();

    reportManagerIface = objServer->add_unique_interface(
        reportManagerPath, reportManagerIfaceName, [this](auto& dbusIface) {
        dbusIface.register_property_r("MaxReports", size_t{},
                                      sdbusplus::vtable::property_::const_,
                                      [](const auto&) { return maxReports; });
        dbusIface.register_property_r(
            "MinInterval", uint64_t{}, sdbusplus::vtable::property_::const_,
            [](const auto&) -> uint64_t { return minInterval.count(); });
        dbusIface.register_property_r(
            "SupportedOperationTypes", std::vector<std::string>{},
            sdbusplus::vtable::property_::const_,
            [](const auto&) -> std::vector<std::string> {
            return utils::transform<std::vector>(
                utils::convDataOperationType,
                [](const auto& item) { return std::string(item.first); });
        });
        dbusIface.register_method(
            "AddReport",
            [this](boost::asio::yield_context& yield, std::string reportId,
                   std::string reportName, std::string reportingType,
                   std::string reportUpdates, uint64_t appendLimit,
                   std::vector<std::string> reportActions, uint64_t interval,
                   ReadingParameters readingParameters, bool enabled) {
            if (reportingType.empty())
            {
                reportingType = utils::enumToString(ReportingType::onRequest);
            }

            if (reportUpdates.empty())
            {
                reportUpdates = utils::enumToString(ReportUpdates::overwrite);
            }

            if (appendLimit == std::numeric_limits<uint64_t>::max())
            {
                appendLimit = maxAppendLimit;
            }

            if (interval == std::numeric_limits<uint64_t>::max())
            {
                interval = 0;
            }

            return addReport(yield, reportId, reportName,
                             utils::toReportingType(reportingType),
                             utils::transform(reportActions,
                                              [](const auto& reportAction) {
                return utils::toReportAction(reportAction);
            }),
                             Milliseconds(interval), appendLimit,
                             utils::toReportUpdates(reportUpdates),
                             readingParameters, enabled)
                .getPath();
        });
    });
}

void ReportManager::removeReport(const interfaces::Report* report)
{
    reports.erase(
        std::remove_if(reports.begin(), reports.end(),
                       [report](const auto& x) { return report == x.get(); }),
        reports.end());
}

void ReportManager::verifyAddReport(
    const std::string& reportId, const std::string& reportName,
    const ReportingType reportingType, Milliseconds interval,
    const ReportUpdates reportUpdates, const uint64_t appendLimit,
    const std::vector<LabeledMetricParameters>& readingParams)
{
    namespace ts = utils::tstring;

    if (reports.size() >= maxReports)
    {
        throw sdbusplus::exception::SdBusError(
            static_cast<int>(std::errc::too_many_files_open),
            "Reached maximal report count");
    }

    if (appendLimit > maxAppendLimit &&
        appendLimit != std::numeric_limits<uint64_t>::max())
    {
        throw errors::InvalidArgument("AppendLimit", "Out of range.");
    }

    if ((reportingType == ReportingType::periodic && interval < minInterval) ||
        (reportingType != ReportingType::periodic &&
         interval != Milliseconds{0}))
    {
        throw errors::InvalidArgument("Interval");
    }

    size_t metricCount = 0;
    for (auto metricParam : readingParams)
    {
        auto metricParamsVec =
            metricParam.at_label<utils::tstring::SensorPath>();
        metricCount += metricParamsVec.size();
    }

    if (readingParams.size() > maxNumberMetrics ||
        metricCount > maxNumberMetrics)
    {
        throw errors::InvalidArgument("MetricParams", "Too many.");
    }

    for (const LabeledMetricParameters& item : readingParams)
    {
        utils::toOperationType(
            utils::toUnderlying(item.at_label<ts::OperationType>()));
    }
}

interfaces::Report& ReportManager::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)
{
    auto labeledMetricParams = reportFactory->convertMetricParams(yield,
                                                                  metricParams);

    return addReport(reportId, reportName, reportingType, reportActions,
                     interval, appendLimit, reportUpdates,
                     std::move(labeledMetricParams), enabled, Readings{});
}

interfaces::Report& ReportManager::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> labeledMetricParams,
    const bool enabled, Readings readings)
{
    const auto existingReportIds = utils::transform(
        reports, [](const auto& report) { return report->getId(); });

    auto [id, name] = utils::makeIdName(reportId, reportName, reportNameDefault,
                                        existingReportIds);

    verifyAddReport(id, name, reportingType, interval, reportUpdates,
                    appendLimit, labeledMetricParams);

    reports.emplace_back(
        reportFactory->make(id, name, reportingType, reportActions, interval,
                            appendLimit, reportUpdates, *this, *reportStorage,
                            labeledMetricParams, enabled, std::move(readings)));
    return *reports.back();
}

void ReportManager::loadFromPersistent()
{
    std::vector<interfaces::JsonStorage::FilePath> paths =
        reportStorage->list();

    for (const auto& path : paths)
    {
        std::optional<nlohmann::json> data = reportStorage->load(path);
        try
        {
            size_t version = data->at("Version").get<size_t>();
            if (version != Report::reportVersion)
            {
                throw std::logic_error("Invalid version");
            }
            bool enabled = data->at("Enabled").get<bool>();
            std::string& id = data->at("Id").get_ref<std::string&>();
            std::string& name = data->at("Name").get_ref<std::string&>();

            uint32_t reportingType = data->at("ReportingType").get<uint32_t>();
            std::vector<ReportAction> reportActions = utils::transform(
                data->at("ReportActions").get<std::vector<uint32_t>>(),
                [](const auto reportAction) {
                return utils::toReportAction(reportAction);
            });
            uint64_t interval = data->at("Interval").get<uint64_t>();
            uint64_t appendLimit = data->at("AppendLimit").get<uint64_t>();
            uint32_t reportUpdates = data->at("ReportUpdates").get<uint32_t>();
            auto readingParameters =
                data->at("ReadingParameters")
                    .get<std::vector<LabeledMetricParameters>>();

            Readings readings = {};

            if (auto it = data->find("MetricValues"); it != data->end())
            {
                const auto labeledReadings = it->get<LabeledReadings>();
                readings = utils::toReadings(labeledReadings);
            }

            addReport(id, name, utils::toReportingType(reportingType),
                      reportActions, Milliseconds(interval), appendLimit,
                      utils::toReportUpdates(reportUpdates),
                      std::move(readingParameters), enabled,
                      std::move(readings));
        }
        catch (const std::exception& e)
        {
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "Failed to load report from storage",
                phosphor::logging::entry(
                    "FILENAME=%s",
                    static_cast<std::filesystem::path>(path).c_str()),
                phosphor::logging::entry("EXCEPTION_MSG=%s", e.what()));
            reportStorage->remove(path);
        }
    }
}
