'use strict';

// Session 8 (A1 board) — systemHealth: box vitals, pure + injectable.

const { getSystemHealth, healthIssues, THRESHOLDS } = require('../../src/services/systemHealth');

describe('getSystemHealth', () => {
  test('computes disk_pct from statfs and mem_pct from os', async () => {
    const fsImpl = { statfs: async () => ({ blocks: 1000, bavail: 400 }) };   // 60% used
    const osImpl = { totalmem: () => 100, freemem: () => 25 };                // 75% used
    const h = await getSystemHealth({ fsImpl, osImpl });
    expect(h).toEqual({ disk_pct: 60, mem_pct: 75 });
  });

  test('a failed statfs degrades disk_pct to null, mem still reports', async () => {
    const fsImpl = { statfs: async () => { throw new Error('EACCES'); } };
    const osImpl = { totalmem: () => 10, freemem: () => 1 };
    const h = await getSystemHealth({ fsImpl, osImpl });
    expect(h.disk_pct).toBeNull();
    expect(h.mem_pct).toBe(90);
  });

  test('zero/invalid totals degrade to null rather than dividing by zero', async () => {
    const h = await getSystemHealth({
      fsImpl: { statfs: async () => ({ blocks: 0, bavail: 0 }) },
      osImpl: { totalmem: () => 0, freemem: () => 0 },
    });
    expect(h).toEqual({ disk_pct: null, mem_pct: null });
  });

  test('real (uninjected) call returns numbers on this box', async () => {
    const h = await getSystemHealth();
    expect(h.disk_pct === null || (h.disk_pct >= 0 && h.disk_pct <= 100)).toBe(true);
    expect(h.mem_pct).toBeGreaterThanOrEqual(0);
    expect(h.mem_pct).toBeLessThanOrEqual(100);
  });
});

describe('healthIssues', () => {
  test('thresholds: disk > 85, mem > 90 — strictly greater', () => {
    expect(healthIssues({ disk_pct: 85, mem_pct: 90 })).toEqual([]);
    expect(healthIssues({ disk_pct: 86, mem_pct: 90 })).toEqual(['disk at 86% (threshold 85%)']);
    expect(healthIssues({ disk_pct: 40, mem_pct: 91 })).toEqual(['memory at 91% (threshold 90%)']);
    expect(healthIssues({ disk_pct: 99, mem_pct: 99 })).toHaveLength(2);
  });

  test('null probes never flag; copy carries no exclamation points', () => {
    expect(healthIssues({ disk_pct: null, mem_pct: null })).toEqual([]);
    expect(healthIssues(null)).toEqual([]);
    for (const line of healthIssues({ disk_pct: 99, mem_pct: 99 })) {
      expect(line).not.toContain('!');
    }
  });

  test('exported thresholds match the spec', () => {
    expect(THRESHOLDS).toEqual({ disk_pct: 85, mem_pct: 90 });
  });
});
