import fs from 'node:fs/promises';
import path from 'node:path';
import { readSessionDirEnv, resolveClockDir } from './paths.js';
import { cleanExpiredTasks, coerceState, nowMs } from './state.js';
import { readJsonFile, writeJsonFileAtomic } from './io.js';
import { startClockNtpSyncIfNeeded } from './ntp.js';
let daemonStarted = false;
let daemonTimer;
let daemonConfig;
export async function startClockDaemonIfNeeded(config) {
    if (daemonStarted) {
        return;
    }
    const sessionDir = readSessionDirEnv();
    if (!sessionDir) {
        return;
    }
    daemonStarted = true;
    daemonConfig = config;
    // Best-effort NTP sync (do not block daemon startup).
    void startClockNtpSyncIfNeeded(config);
    const tickOnce = async () => {
        const effective = daemonConfig;
        if (!effective)
            return;
        const base = readSessionDirEnv();
        if (!base)
            return;
        const dir = resolveClockDir(base);
        try {
            const entries = await fs.readdir(dir, { withFileTypes: true });
            const at = nowMs();
            for (const entry of entries) {
                if (!entry.isFile())
                    continue;
                if (!entry.name.endsWith('.json'))
                    continue;
                const filePath = path.join(dir, entry.name);
                try {
                    const raw = await readJsonFile(filePath);
                    const sessionId = entry.name.slice(0, -'.json'.length);
                    const state = coerceState(raw, sessionId);
                    const cleaned = cleanExpiredTasks(state.tasks, effective, at);
                    if (!cleaned.length) {
                        await fs.rm(filePath, { force: true });
                        continue;
                    }
                    if (cleaned.length !== state.tasks.length) {
                        const next = {
                            ...state,
                            tasks: cleaned,
                            updatedAtMs: at
                        };
                        await writeJsonFileAtomic(filePath, next);
                    }
                }
                catch {
                    // best-effort: ignore per-file errors
                }
            }
        }
        catch {
            // best-effort: ignore global scan errors
        }
    };
    // Startup scan (best-effort).
    void tickOnce();
    if (config.tickMs > 0) {
        daemonTimer = setInterval(() => {
            void tickOnce();
        }, config.tickMs);
        daemonTimer.unref?.();
    }
}
export async function stopClockDaemonForTests() {
    if (daemonTimer) {
        clearInterval(daemonTimer);
        daemonTimer = undefined;
    }
    daemonStarted = false;
    daemonConfig = undefined;
}
