/**
 * P1-2 smoke test — NotificationRule conditions are honoured.
 *
 * Run: npx tsx scripts/smoke/p1-2-rule-conditions.ts
 */
import './_lib';
import { ok, fail } from './_lib';

const prismaMod = require('../../src/lib/prisma') as { prisma: Record<string, unknown> };

let ruleFixture: unknown[] = [];
prismaMod.prisma.notificationRule = {
    findMany: async () => ruleFixture,
} as unknown;
prismaMod.prisma.notificationChannel = {
    findMany: async () => [],
} as unknown;

const { RulesEngineService, invalidateRulesCache } = require('../../src/lib/services/rules-engine.service') as typeof import('../../src/lib/services/rules-engine.service');

function ruleWith(conditions: Record<string, unknown>) {
    return {
        id: 1,
        name: 'test',
        enabled: true,
        scope: 'global',
        scopeId: null,
        monitorTypes: null,
        triggers: [{ event: 'monitor_down' }],
        monitors: [],
        country: null,
        user: null,
        channelIds: null,
        conditions: JSON.stringify(conditions),
        schedule: null,
    };
}

const baseCtx = {
    trigger: 'monitor_down',
    monitorId: 1,
    monitorType: 'http',
    monitorRegion: 'KE',
};

async function main(): Promise<void> {
    // audit3-2 (2026-05-28): RulesEngineService caches findMany on a
    // 30 s TTL. Mutation routes call invalidateRulesCache() on POST /
    // PUT / DELETE. This smoke mutates `ruleFixture` directly (bypassing
    // those routes), so it must invalidate manually whenever the
    // fixture changes.
    ruleFixture = [ruleWith({ latencyThreshold: 500 })];
    invalidateRulesCache();
    const ml1 = await RulesEngineService.evaluate({ ...baseCtx, latency: 800 });
    if (ml1.length !== 1) fail('latency >= threshold', `expected 1 match got ${ml1.length}`);
    ok('latencyThreshold 500 + latency 800 → matches');

    const ml2 = await RulesEngineService.evaluate({ ...baseCtx, latency: 100 });
    if (ml2.length !== 0) fail('latency < threshold', `expected 0 match got ${ml2.length}`);
    ok('latencyThreshold 500 + latency 100 → rejected');

    ruleFixture = [ruleWith({ consecutiveFailures: 3 })];
    invalidateRulesCache();
    const mc1 = await RulesEngineService.evaluate({ ...baseCtx, consecutiveStatus: 5 });
    if (mc1.length !== 1) fail('consec >= threshold', `expected 1 match got ${mc1.length}`);
    ok('consecutiveFailures 3 + consecutiveStatus 5 → matches');

    const mc2 = await RulesEngineService.evaluate({ ...baseCtx, consecutiveStatus: 1 });
    if (mc2.length !== 0) fail('consec < threshold', `expected 0 match got ${mc2.length}`);
    ok('consecutiveFailures 3 + consecutiveStatus 1 → rejected');

    ok('P1-2 rule-conditions', 'latency + consecutive-failures gates now actually fire');
}

main().catch((err) => fail('P1-2 rule-conditions', String(err)));
