/**
 * 飞书文档订阅注册表 —— 把「一个被订阅的文档」绑到「一条会话」。
 *
 * 设计约束（申晗拍板）：
 *   • 一条会话可订阅多个文档（N 行同 sessionAnchor）。
 *   • **一个文档只绑一条活跃会话**：本表以 fileToken 为主键，重复订阅直接覆盖，
 *     天然保证「一条评论事件只命中一条会话」。
 *
 * 文件按观察者 app 隔离（`doc-subscriptions-<larkAppId>.json`）：飞书 open_id /
 * 文档可见性都是 per-app 的，且生产是「一 bot 一 daemon」，per-app 文件让每个
 * daemon 只读写自己那份，互不串。
 *
 * 写者只有 daemon 进程本身（命令处理 / 事件 / dashboard-IPC 都在 daemon 内），
 * 单写者，原子写（唯一 tmp + rename）即可，无需跨进程锁。
 */
import { readFileSync, existsSync, mkdirSync } from 'node:fs';
import { join } from 'node:path';
import { atomicWriteFileSync } from '../utils/atomic-write.js';
function filePath(dataDir, larkAppId) {
    return join(dataDir, `doc-subscriptions-${larkAppId}.json`);
}
function readFile(dataDir, larkAppId) {
    const fp = filePath(dataDir, larkAppId);
    if (!existsSync(fp))
        return {};
    try {
        const parsed = JSON.parse(readFileSync(fp, 'utf-8'));
        if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))
            return parsed;
    }
    catch { /* corrupt — 当空处理 */ }
    return {};
}
function writeFile(dataDir, larkAppId, data) {
    if (!existsSync(dataDir))
        mkdirSync(dataDir, { recursive: true });
    atomicWriteFileSync(filePath(dataDir, larkAppId), JSON.stringify(data, null, 2) + '\n');
}
/**
 * 新增 / 覆盖一条订阅（fileToken 主键 → 重订阅覆盖旧绑定 = 1 文档:1 会话）。
 * 返回被覆盖掉的旧订阅（如果该文档此前绑在别的会话上），调用方据此退订旧的 /
 * 提示用户。
 */
export function putDocSubscription(dataDir, larkAppId, sub) {
    const data = readFile(dataDir, larkAppId);
    const previous = data[sub.fileToken];
    data[sub.fileToken] = sub;
    writeFile(dataDir, larkAppId, data);
    return { previous };
}
/** 取某文档的订阅（评论事件来后据 fileToken 定位会话）。无则 null。 */
export function getDocSubscription(dataDir, larkAppId, fileToken) {
    return readFile(dataDir, larkAppId)[fileToken] ?? null;
}
/** 删一条订阅，返回被删的那条（无则 undefined）。 */
export function removeDocSubscription(dataDir, larkAppId, fileToken) {
    const data = readFile(dataDir, larkAppId);
    const removed = data[fileToken];
    if (!removed)
        return undefined;
    delete data[fileToken];
    writeFile(dataDir, larkAppId, data);
    return removed;
}
/** 列某会话锚点上的所有订阅（/doc list、/close 退订时用）。 */
export function listDocSubscriptionsForSession(dataDir, larkAppId, sessionAnchor) {
    return Object.values(readFile(dataDir, larkAppId)).filter(s => s.sessionAnchor === sessionAnchor);
}
/** 列本 app 下全部订阅（daemon 重启恢复 + dashboard 展示）。 */
export function listAllDocSubscriptions(dataDir, larkAppId) {
    return Object.values(readFile(dataDir, larkAppId));
}
/** 改某文档订阅的触发范围（dashboard）。返回是否命中。 */
export function setCommentTriggerMode(dataDir, larkAppId, fileToken, mode) {
    const data = readFile(dataDir, larkAppId);
    const sub = data[fileToken];
    if (!sub)
        return false;
    sub.commentTriggerMode = mode;
    writeFile(dataDir, larkAppId, data);
    return true;
}
//# sourceMappingURL=doc-subs-store.js.map