import { describe, it, expect } from 'vitest';
import { validateAbi, validateContractAbi } from '../src/helpers/abi.js';
import type { Abi } from 'viem';

// ---------------------------------------------------------------------------
// validateAbi
// ---------------------------------------------------------------------------

describe('validateAbi', () => {
  it('returns the exact same ABI reference it receives', () => {
    const abi: Abi = [
      {
        name: 'transfer',
        type: 'function',
        stateMutability: 'nonpayable',
        inputs: [
          { name: 'to', type: 'address' },
          { name: 'amount', type: 'uint256' },
        ],
        outputs: [{ name: '', type: 'bool' }],
      },
    ];
    const result = validateAbi(abi);
    expect(result).toBe(abi);
  });

  it('returns an empty ABI unchanged', () => {
    const abi: Abi = [];
    expect(validateAbi(abi)).toBe(abi);
  });

  it('preserves all entries in a multi-entry ABI', () => {
    const abi: Abi = [
      {
        name: 'mint',
        type: 'function',
        stateMutability: 'nonpayable',
        inputs: [],
        outputs: [],
      },
      {
        name: 'Transfer',
        type: 'event',
        inputs: [
          { name: 'from', type: 'address', indexed: true },
          { name: 'to', type: 'address', indexed: true },
          { name: 'value', type: 'uint256', indexed: false },
        ],
        anonymous: false,
      },
    ];
    const result = validateAbi(abi);
    expect(result).toHaveLength(2);
    expect(result).toBe(abi);
  });
});

// ---------------------------------------------------------------------------
// validateContractAbi
// ---------------------------------------------------------------------------

describe('validateContractAbi', () => {
  it('returns the abi property from the contract object', () => {
    const abi: Abi = [
      {
        name: 'balanceOf',
        type: 'function',
        stateMutability: 'view',
        inputs: [{ name: 'account', type: 'address' }],
        outputs: [{ name: '', type: 'uint256' }],
      },
    ];
    const contract = { abi, address: '0xdeadbeef' };
    const result = validateContractAbi(contract);
    expect(result).toBe(abi);
  });

  it('works with an empty abi property', () => {
    const contract = { abi: [] as Abi };
    const result = validateContractAbi(contract);
    expect(result).toEqual([]);
  });

  it('does not return any other property of the contract object', () => {
    const abi: Abi = [];
    const contract = { abi, address: '0x1234', name: 'MyContract' };
    const result = validateContractAbi(contract);
    expect(result).toBe(abi);
    // result is just the ABI array, not the full contract object
    expect(Array.isArray(result)).toBe(true);
  });
});
