"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.listTopics = listTopics;
exports.getTopic = getTopic;
exports.createTopic = createTopic;
exports.updateTopic = updateTopic;
exports.deleteTopic = deleteTopic;
exports.upsertTopicOnPublish = upsertTopicOnPublish;
exports.seedTopic = seedTopic;
exports.resetTopic = resetTopic;
const db_1 = require("../../lib/db");
const sql_1 = require("./sql");
async function listTopics(filters = {}) {
    const pool = (0, db_1.getPool)();
    const limit = filters.limit ?? 50;
    const offset = filters.offset ?? 0;
    const category = filters.category ?? null;
    const search = filters.search ?? null;
    const [dataResult, countResult] = await Promise.all([
        pool.query(sql_1.LIST_TOPICS, [category, search, limit, offset]),
        pool.query(sql_1.COUNT_TOPICS, [category, search]),
    ]);
    return {
        topics: dataResult.rows,
        total: countResult.rows[0]?.total ?? 0,
    };
}
async function getTopic(topic) {
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.GET_TOPIC, [topic]);
    if (!rows[0])
        return null;
    const { rows: subscribers } = await pool.query(sql_1.LIST_SUBSCRIBERS, [topic]);
    return { ...rows[0], subscribers };
}
async function createTopic(data) {
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.INSERT_TOPIC, [
        data.topic,
        data.description ?? null,
        data.category,
        data.payload_schema ? JSON.stringify(data.payload_schema) : null,
        data.example_payload ? JSON.stringify(data.example_payload) : null,
        data.source ?? 'app',
        data.tags ?? [],
    ]);
    return rows[0];
}
async function updateTopic(topic, data) {
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.UPDATE_TOPIC, [
        topic,
        data.description ?? null,
        data.category ?? null,
        data.payload_schema ? JSON.stringify(data.payload_schema) : null,
        data.example_payload ? JSON.stringify(data.example_payload) : null,
        data.tags ?? null,
    ]);
    return rows[0] ?? null;
}
async function deleteTopic(topic) {
    const pool = (0, db_1.getPool)();
    const { rowCount } = await pool.query(sql_1.DELETE_TOPIC, [topic]);
    return (rowCount ?? 0) > 0;
}
/**
 * Auto-register or update a topic on publish (learn-on-first-use).
 * Creates the entry on first publish; updates last_seen on subsequent publishes.
 */
async function upsertTopicOnPublish(topic, data, source) {
    const pool = (0, db_1.getPool)();
    const category = topic.startsWith('app.') ? 'app' : topic.split('.')[0];
    await pool.query(sql_1.UPSERT_ON_PUBLISH, [
        topic,
        category,
        source ?? 'mcp-tool',
        data ? JSON.stringify(data) : null,
    ]);
}
/**
 * Seed a topic at startup (insert-if-absent).
 * Conflict on topic — DB is source of truth after first boot.
 */
async function seedTopic(data) {
    const pool = (0, db_1.getPool)();
    const { rowCount } = await pool.query(sql_1.SEED_TOPIC, [
        data.topic,
        data.description,
        data.category,
        data.payload_schema ? JSON.stringify(data.payload_schema) : null,
        data.example_payload ? JSON.stringify(data.example_payload) : null,
        data.source ?? 'system',
        data.tags ?? [],
    ]);
    return (rowCount ?? 0) > 0;
}
/**
 * Reset a topic at startup — config is source of truth.
 * Overwrites description, category, schema, tags on every boot.
 * Used when `reset: true` is set in static topic config.
 */
async function resetTopic(data) {
    const pool = (0, db_1.getPool)();
    await pool.query(sql_1.RESET_TOPIC, [
        data.topic,
        data.description,
        data.category,
        data.payload_schema ? JSON.stringify(data.payload_schema) : null,
        data.example_payload ? JSON.stringify(data.example_payload) : null,
        data.source ?? 'config',
        data.tags ?? [],
    ]);
}
