import { uptimePct, avgLatency, percentile, addAgg, EMPTY_AGG, type Agg } from '../executive-metrics';

describe('executive-metrics pure helpers', () => {
    it('uptimePct: an empty window is treated as 100% (no data = no known downtime)', () => {
        expect(uptimePct(EMPTY_AGG)).toBe(100);
    });

    it('uptimePct: up / total', () => {
        expect(uptimePct({ total: 200, up: 199, latSum: 0, latCount: 0 })).toBeCloseTo(99.5, 5);
        expect(uptimePct({ total: 4, up: 3, latSum: 0, latCount: 0 })).toBe(75);
    });

    it('avgLatency: weighted mean of latSum/latCount; 0 when no samples', () => {
        expect(avgLatency({ total: 10, up: 10, latSum: 1000, latCount: 5 })).toBe(200);
        expect(avgLatency(EMPTY_AGG)).toBe(0);
    });

    it('addAgg: sums each field — this is how the raw + hourly tiers combine', () => {
        const raw: Agg = { total: 10, up: 9, latSum: 100, latCount: 8 };
        const hourly: Agg = { total: 5, up: 5, latSum: 50, latCount: 5 };
        expect(addAgg(raw, hourly)).toEqual({ total: 15, up: 14, latSum: 150, latCount: 13 });
    });

    it('percentile: nearest-rank on a sorted ascending array', () => {
        const s = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
        expect(percentile(s, 50)).toBe(50);
        expect(percentile(s, 95)).toBe(100);
        expect(percentile(s, 99)).toBe(100);
        expect(percentile([42], 50)).toBe(42);
        expect(percentile([], 50)).toBe(0);
    });
});
