import { AppService } from './app.service';

describe('AppService readiness', () => {
  const createService = (options: { mongoFails?: boolean; storageWritable?: boolean } = {}) => {
    const connection = { db: { admin: () => ({
      ping: options.mongoFails ? jest.fn().mockRejectedValue(new Error('mongo down')) : jest.fn().mockResolvedValue({ ok: 1 }),
    }) } };
    const redis = { isEnabled: jest.fn().mockReturnValue(false), getClient: jest.fn() };
    const storage = { getHealth: jest.fn().mockResolvedValue({
      provider: 'local', local: { readable: true, writable: options.storageWritable ?? true },
    }) };
    const shutdown = {
      isDraining: jest.fn().mockReturnValue(false),
      getActiveRequests: jest.fn().mockReturnValue(0),
    };
    return {
      service: new AppService(connection as any, redis as any, storage as any, shutdown as any, { isReady: () => true } as any),
      shutdown,
    };
  };

  it('reports ready when required dependencies are healthy', async () => {
    await expect(createService().service.getReadiness()).resolves.toEqual(expect.objectContaining({ status: 'ready' }));
  });

  it('reports degraded and identifies failed dependencies', async () => {
    const result = await createService({ mongoFails: true, storageWritable: false }).service.getReadiness();
    expect(result).toEqual(expect.objectContaining({ status: 'degraded' }));
    expect((result.checks as any).mongodb.status).toBe('down');
    expect((result.checks as any).storage.status).toBe('down');
  });

  it('reports draining immediately during graceful shutdown', async () => {
    const { service, shutdown } = createService();
    shutdown.isDraining.mockReturnValue(true);
    shutdown.getActiveRequests.mockReturnValue(2);

    await expect(service.getReadiness()).resolves.toEqual(
      expect.objectContaining({ status: 'draining', activeRequests: 2 }),
    );
  });
});
