import { IpWhitelistService } from './ip-whitelist.service';

describe('IpWhitelistService IP & CIDR Matching', () => {
  let service: IpWhitelistService;
  let mockDb: any;

  beforeEach(() => {
    mockDb = {
      ip_whitelists: {
        findMany: jest.fn(),
      },
    };
    service = new IpWhitelistService(mockDb);
  });

  it('should normalize localhost and IPv6 mapped addresses', () => {
    expect(service.normalizeIp('::1')).toBe('127.0.0.1');
    expect(service.normalizeIp('::ffff:127.0.0.1')).toBe('127.0.0.1');
    expect(service.normalizeIp('::ffff:192.168.1.50')).toBe('192.168.1.50');
    expect(service.normalizeIp('10.0.0.1')).toBe('10.0.0.1');
  });

  it('should allow access if no active whitelists configured', async () => {
    mockDb.ip_whitelists.findMany.mockResolvedValue([]);
    const allowed = await service.isIpAllowed('owner-1', '192.168.1.50');
    expect(allowed).toBe(true);
  });

  it('should match exact IP', async () => {
    mockDb.ip_whitelists.findMany.mockResolvedValue([
      { ip_or_cidr: '103.20.10.5', is_active: true },
    ]);

    expect(await service.isIpAllowed('owner-1', '103.20.10.5')).toBe(true);
    expect(await service.isIpAllowed('owner-1', '103.20.10.6')).toBe(false);
  });

  it('should match CIDR subnets (e.g. /24 and /16)', async () => {
    mockDb.ip_whitelists.findMany.mockResolvedValue([
      { ip_or_cidr: '192.168.1.0/24', is_active: true },
      { ip_or_cidr: '10.0.0.0/16', is_active: true },
    ]);

    expect(await service.isIpAllowed('owner-1', '192.168.1.1')).toBe(true);
    expect(await service.isIpAllowed('owner-1', '192.168.1.254')).toBe(true);
    expect(await service.isIpAllowed('owner-1', '192.168.2.1')).toBe(false);

    expect(await service.isIpAllowed('owner-1', '10.0.50.22')).toBe(true);
    expect(await service.isIpAllowed('owner-1', '10.1.0.1')).toBe(false);
  });
});
