#include "message_bus/pipeline/stages/3_filters/ProtocolParseFilter.h"

#include <QDir>
#include <QFileInfo>

namespace softbus::message_bus::pipeline::stages::filters
{

ProtocolParseFilter::ProtocolParseFilter() = default;

bool ProtocolParseFilter::process(softbus::core::models::DOMMessage& message)
{
    if (!ensureLoaded()) {
        return true;
    }
    // Message-stage filter: only normalize quality by metadata range.
    if (!message.metaRef) {
        return true;
    }
    const auto* meta = m_metadataRegistry.findById(message.metaRef->metadataId);
    if (!meta) {
        return true;
    }
    const double v = std::visit(
        [](const auto& x) { return static_cast<double>(x); },
        message.value);
    if (meta->maxValue > meta->minValue && (v < meta->minValue || v > meta->maxValue)) {
        message.quality = softbus::core::models::DataQuality::UNCERTAIN;
        message.appendTrace(QStringLiteral("filter:range_check -> uncertain"));
    }
    return true;
}

softbus::core::models::EnrichedMessage
ProtocolParseFilter::enrich(const softbus::core::models::DOMMessage& message)
{
    softbus::core::models::EnrichedMessage out;
    out.sourceMessageId = message.messageId;
    out.logicalName = message.metaRef ? message.metaRef->name : message.messageId;
    out.unit = message.metaRef ? message.metaRef->unit : QString();
    out.engineeringValue = message.value;
    out.quality = message.quality;
    out.attributes = message.attributes;
    out.traceLog = message.traceLog;
    return out;
}

bool ProtocolParseFilter::ensureLoaded() const
{
    std::call_once(m_loadOnce, [this]() {
        QString configBase = qEnvironmentVariable("SOFTBUS_CONFIG_DIR");
        if (!configBase.isEmpty() && !configBase.endsWith(QChar('/'))) {
            configBase.append(QChar('/'));
        }
        const QString homeCfg = configBase.isEmpty()
            ? (QDir::homePath() + QStringLiteral("/softbus/config/"))
            : configBase;
        const QString metaHome = homeCfg + QStringLiteral("metadata_dictionary.json");
        const QString metaLocal = QStringLiteral("config/metadata_dictionary.json");
        const QString metaPath = QFileInfo::exists(metaHome) ? metaHome : metaLocal;
        m_loaded = m_metadataRegistry.loadFromFile(metaPath);
    });
    return m_loaded;
}

} // namespace softbus::message_bus::pipeline::stages::filters

