/**
 * Tests for ISO-4217 compliant symbol validation and parsing.
 */

import {
  isValidNativeSymbol,
  isValidBridgedSymbol,
  parseSymbol,
} from './iso4217-symbol-validator';
import { V0_TO_V1_SYMBOL_MAP, getV1IdentityForV0Symbol } from '../config/iso4217-symbol-registry';

describe('isValidNativeSymbol', () => {
  it('accepts valid 6-char native symbols', () => {
    expect(isValidNativeSymbol('cAUSDT')).toBe(true);
    expect(isValidNativeSymbol('cXUSDC')).toBe(true);
    expect(isValidNativeSymbol('cAUSDC')).toBe(true);
    expect(isValidNativeSymbol('cXEURC')).toBe(true);
    expect(isValidNativeSymbol('cAGBPT')).toBe(true);
  });

  it('rejects v0 legacy (no chain designator)', () => {
    expect(isValidNativeSymbol('cUSDT')).toBe(false);
    expect(isValidNativeSymbol('cUSDC')).toBe(false);
  });

  it('rejects missing type', () => {
    expect(isValidNativeSymbol('cAUSD')).toBe(false);
  });

  it('rejects wrong length', () => {
    expect(isValidNativeSymbol('cAUSDCX')).toBe(false);
    expect(isValidNativeSymbol('cAUSD')).toBe(false);
    expect(isValidNativeSymbol('')).toBe(false);
  });

  it('rejects invalid ISO code', () => {
    expect(isValidNativeSymbol('cAXXXT')).toBe(false);
  });

  it('rejects invalid chain designator', () => {
    expect(isValidNativeSymbol('cBUSDT')).toBe(false);
  });
});

describe('isValidBridgedSymbol', () => {
  it('accepts valid 7-char bridged symbols', () => {
    expect(isValidBridgedSymbol('cWAUSDT')).toBe(true);
    expect(isValidBridgedSymbol('cWXUSDC')).toBe(true);
    expect(isValidBridgedSymbol('cWAEURC')).toBe(true);
  });

  it('rejects native 6-char', () => {
    expect(isValidBridgedSymbol('cAUSDT')).toBe(false);
  });

  it('rejects missing W at position 2', () => {
    expect(isValidBridgedSymbol('cWAUSD')).toBe(false);
    expect(isValidBridgedSymbol('cAUSDTX')).toBe(false);
  });

  it('rejects invalid length', () => {
    expect(isValidBridgedSymbol('cWAUSD')).toBe(false);
    expect(isValidBridgedSymbol('cWAUSDTW')).toBe(false);
  });
});

describe('parseSymbol', () => {
  it('parses v0 symbols and returns v1 identity', () => {
    const cusdt = parseSymbol('cUSDT');
    expect(cusdt).not.toBeNull();
    expect(cusdt!.type).toBe('v0');
    expect(cusdt!.iso).toBe('USD');
    expect(cusdt!.typeChar).toBe('T');
    expect(cusdt!.originChain).toBe('X');
    expect(cusdt!.v1Identity).toEqual({ iso: 'USD', type: 'T', originChain: 'X' });

    const cusdc = parseSymbol('cUSDC');
    expect(cusdc).not.toBeNull();
    expect(cusdc!.type).toBe('v0');
    expect(cusdc!.iso).toBe('USD');
    expect(cusdc!.typeChar).toBe('C');
    expect(cusdc!.originChain).toBe('X');
  });

  it('parses native 6-char symbols', () => {
    const p = parseSymbol('cAUSDT');
    expect(p).not.toBeNull();
    expect(p!.type).toBe('native');
    expect(p!.iso).toBe('USD');
    expect(p!.typeChar).toBe('T');
    expect(p!.originChain).toBe('A');
  });

  it('parses bridged 7-char symbols', () => {
    const p = parseSymbol('cWXUSDC');
    expect(p).not.toBeNull();
    expect(p!.type).toBe('bridged');
    expect(p!.iso).toBe('USD');
    expect(p!.typeChar).toBe('C');
    expect(p!.originChain).toBe('X');
  });

  it('returns null for invalid or unknown symbols', () => {
    expect(parseSymbol('cAUSD')).toBeNull();
    expect(parseSymbol('invalid')).toBeNull();
    expect(parseSymbol('')).toBeNull();
    expect(parseSymbol(null as unknown as string)).toBeNull();
  });
});

describe('v0 to v1 map lookup', () => {
  it('V0_TO_V1_SYMBOL_MAP has correct entries', () => {
    expect(V0_TO_V1_SYMBOL_MAP.cUSDT).toEqual({ iso: 'USD', type: 'T', originChain: 'X' });
    expect(V0_TO_V1_SYMBOL_MAP.cUSDC).toEqual({ iso: 'USD', type: 'C', originChain: 'X' });
  });

  it('getV1IdentityForV0Symbol returns identity for v0 symbols', () => {
    expect(getV1IdentityForV0Symbol('cUSDT')).toEqual({ iso: 'USD', type: 'T', originChain: 'X' });
    expect(getV1IdentityForV0Symbol('cUSDC')).toEqual({ iso: 'USD', type: 'C', originChain: 'X' });
    expect(getV1IdentityForV0Symbol('cAUSDT')).toBeUndefined();
  });
});
