#pragma once

#include <catch2/catch_test_macros.hpp>
#include <nlohmann/json.hpp>
#include <string>

namespace celuna::tests {

using json = nlohmann::json;

// ============================================================================
// Custom Catch2 Matchers and Macros
// ============================================================================

/**
 * @brief Require that a message was published to a topic
 */
#define REQUIRE_PUBLISHED(io, topic) \
    REQUIRE_MESSAGE(io.wasPublished(topic), "Expected message on topic: " << topic)

/**
 * @brief Require that no message was published to a topic
 */
#define REQUIRE_NOT_PUBLISHED(io, topic) \
    REQUIRE_MESSAGE(!io.wasPublished(topic), "Did not expect message on topic: " << topic)

/**
 * @brief Require specific count of messages on a topic
 */
#define REQUIRE_PUBLISH_COUNT(io, topic, count) \
    REQUIRE(io.countPublished(topic) == count)

// ============================================================================
// JSON Helpers
// ============================================================================

/**
 * @brief Create a minimal valid config for a module
 */
inline json makeConfig(const json& overrides = json::object()) {
    json config = json::object();
    for (auto& [key, value] : overrides.items()) {
        config[key] = value;
    }
    return config;
}

/**
 * @brief Check if JSON contains expected fields
 */
inline bool jsonContains(const json& j, const json& expected) {
    for (auto& [key, value] : expected.items()) {
        if (!j.contains(key) || j[key] != value) {
            return false;
        }
    }
    return true;
}

// ============================================================================
// Test Tags
// ============================================================================

// Module tags
constexpr const char* TAG_SCHEDULER = "[scheduler]";
constexpr const char* TAG_NOTIFICATION = "[notification]";
constexpr const char* TAG_MONITORING = "[monitoring]";
constexpr const char* TAG_AI = "[ai]";
constexpr const char* TAG_VOICE = "[voice]";
constexpr const char* TAG_STORAGE = "[storage]";

// MCP tags
constexpr const char* TAG_MCP = "[mcp]";
constexpr const char* TAG_MCP_TYPES = "[mcp][types]";
constexpr const char* TAG_MCP_TRANSPORT = "[mcp][transport]";
constexpr const char* TAG_MCP_CLIENT = "[mcp][client]";

// Common tags
constexpr const char* TAG_INTEGRATION = "[integration]";
constexpr const char* TAG_UNIT = "[unit]";

} // namespace celuna::tests
