import { describe, it, expect } from 'vitest';
import { isPrivateIPv4, isPrivateIPv6, isHostAllowed, checkSSRF } from './ssrf.js';

describe('isPrivateIPv4', () => {
  it('127.x はプライベート', () => {
    expect(isPrivateIPv4('127.0.0.1')).toBe(true);
    expect(isPrivateIPv4('127.255.255.255')).toBe(true);
  });
  it('10.x はプライベート', () => {
    expect(isPrivateIPv4('10.0.0.1')).toBe(true);
    expect(isPrivateIPv4('10.255.255.255')).toBe(true);
  });
  it('172.16-31.x はプライベート', () => {
    expect(isPrivateIPv4('172.16.0.1')).toBe(true);
    expect(isPrivateIPv4('172.31.255.255')).toBe(true);
    expect(isPrivateIPv4('172.15.0.1')).toBe(false);
    expect(isPrivateIPv4('172.32.0.1')).toBe(false);
  });
  it('192.168.x はプライベート', () => {
    expect(isPrivateIPv4('192.168.0.1')).toBe(true);
    expect(isPrivateIPv4('192.168.255.255')).toBe(true);
  });
  it('169.254.x はプライベート', () => {
    expect(isPrivateIPv4('169.254.0.1')).toBe(true);
  });
  it('グローバル IP はプライベートではない', () => {
    expect(isPrivateIPv4('8.8.8.8')).toBe(false);
    expect(isPrivateIPv4('1.1.1.1')).toBe(false);
    expect(isPrivateIPv4('203.0.113.1')).toBe(false);
  });
  it('範囲外・不正な形式は false', () => {
    expect(isPrivateIPv4('999.999.999.999')).toBe(false);
    expect(isPrivateIPv4('abc')).toBe(false);
    expect(isPrivateIPv4('')).toBe(false);
  });
});

describe('isPrivateIPv6', () => {
  it('::1 はプライベート', () => {
    expect(isPrivateIPv6('::1')).toBe(true);
  });
  it('fc/fd プレフィックスはプライベート', () => {
    expect(isPrivateIPv6('fc00::1')).toBe(true);
    expect(isPrivateIPv6('fd12:3456::1')).toBe(true);
  });
  it('ブラケット付きでも動作する', () => {
    expect(isPrivateIPv6('[::1]')).toBe(true);
  });
  it('グローバル IPv6 はプライベートではない', () => {
    expect(isPrivateIPv6('2001:db8::1')).toBe(false);
  });
});

describe('isHostAllowed', () => {
  it('allowedHosts に含まれていれば true', () => {
    expect(isHostAllowed('example.com', ['example.com', 'test.com'])).toBe(true);
  });
  it('含まれていなければ false', () => {
    expect(isHostAllowed('evil.com', ['example.com'])).toBe(false);
  });
  it('空リストなら常に false', () => {
    expect(isHostAllowed('example.com', [])).toBe(false);
  });
});

describe('checkSSRF', () => {
  it('localhost はブロック（allowedHosts にない場合）', async () => {
    await expect(checkSSRF('localhost', [])).rejects.toThrow('SSRF blocked');
  });
  it('localhost は allowedHosts に含まれていれば許可', async () => {
    await expect(checkSSRF('localhost', ['localhost'])).resolves.toBeUndefined();
  });
  it('allowedHosts に含まれるホストは許可', async () => {
    await expect(checkSSRF('example.com', ['example.com'])).resolves.toBeUndefined();
  });
});
