import { readFileSync } from 'fs';
import { join } from 'path';
import { ethers } from 'ethers';
import { v3 } from '../src';

const reviewed = JSON.parse(readFileSync(join(
  __dirname,
  'fixtures',
  'v3-reviewed-abi-signatures.json',
), 'utf8')).deployments;

describe('supported final Partnership and Governance ABI additions', () => {
  it('publishes the two read-only Partnership mission-boundary constants', () => {
    const functions = reviewed.partnershipBond.functions as {
      signature: string;
      stateMutability: string;
    }[];
    expect(functions).toHaveLength(55);
    for (const signature of [
      'FLOURISHING_MISSION()',
      'FLOURISHING_NON_CONTROL_BOUNDARY()',
    ]) {
      expect(functions).toContainEqual({ signature, stateMutability: 'view' });
    }
    expect(reviewed.partnershipBond.identity)
      .toBe('0x954aeee609e92a621e726dcae77be193085651626941d582ca2f7f3b7c073d8c');
    expect(v3.V3_ABI_IDENTITIES.partnershipBond).toBe(reviewed.partnershipBond.identity);
  });

  it('uses only the codehash-bound Governance setter and read-only pin getters', () => {
    const functions = reviewed.governance.functions as {
      signature: string;
      stateMutability: string;
    }[];
    const signatures = functions.map((method) => method.signature);
    expect(functions).toHaveLength(45);
    expect(signatures).not.toContain('setCallPolicy(address,bytes4,bool,uint96)');
    expect(functions).toEqual(expect.arrayContaining([
      { signature: 'canonicalRuntimeCodehash(address)', stateMutability: 'view' },
      { signature: 'constructorPinnedPolicyTarget(address)', stateMutability: 'view' },
      { signature: 'pinCanonicalAddress(address,bytes32)', stateMutability: 'nonpayable' },
      {
        signature: 'setCallPolicy(address,bytes4,bool,uint96,bytes32)',
        stateMutability: 'nonpayable',
      },
    ]));
    expect(reviewed.governance.identity)
      .toBe('0xcf81d69fed252f21bfd7661ff53868aa81b9ce1a4a1c89edbec9eaabffa7ad0a');
    expect(v3.V3_ABI_IDENTITIES.governance).toBe(reviewed.governance.identity);

    const callableWrites = v3.V3_WRITE_METHODS.governance;
    for (const selfGovernedSignature of [
      'pinCanonicalAddress(address,bytes32)',
      'setCallPolicy(address,bytes4,bool,uint96,bytes32)',
    ]) {
      expect(callableWrites.map((method) => method.signature)).not.toContain(selfGovernedSignature);
      expect(callableWrites.map((method) => method.selector))
        .not.toContain(ethers.id(selfGovernedSignature).slice(0, 10));
    }
  });
});
