# SPDX-License-Identifier: MIT
import hashlib, json, sys, unittest
from pathlib import Path
ROOT=Path(__file__).resolve().parents[1]; REPO=ROOT.parent; sys.path.insert(0,str(ROOT/'tools'))
from conform import load_json
class MappingTests(unittest.TestCase):
 def test_source_bindings(self):
  m=load_json(ROOT/'mappings/canonical-v3.json')
  for name,b in m['canonicalSources'].items():
   with self.subTest(name): self.assertEqual(hashlib.sha256((REPO/b['path']).read_bytes()).hexdigest(),b['sha256'])
 def test_exact_supported_identity_set(self):
  m=load_json(ROOT/'mappings/canonical-v3.json')
  self.assertEqual({x['sdkName'] for x in m['sdkDeployments']},{'accountabilityBond','partnershipBond','governance','mandateRegistry'})
  self.assertTrue(all(x['deploymentStatus']=='not-deployed-not-authorized' for x in m['sdkDeployments']))
 def test_exact_interface_closure(self):
  m=load_json(ROOT/'mappings/canonical-v3.json')
  self.assertEqual(m['counts'],{'supportedSourceModules':15,'sdkDeployments':4,'sdkWriteDeployments':4,'sdkReadRoutes':11,'generatedV3ApiRoutes':20})
  self.assertEqual({x['sdkName']:x['signatureCount'] for x in m['sdkDeployments']},{'accountabilityBond':36,'partnershipBond':55,'governance':45,'mandateRegistry':24})
  self.assertEqual(
   {x['sdkName']:x['abiIdentity'] for x in m['sdkDeployments']},
   {
    'accountabilityBond':'0x0c18d05c868716fad4bfc1fcfad2da51c83f247de06a7e3871dcece768a9526f',
    'partnershipBond':'0x954aeee609e92a621e726dcae77be193085651626941d582ca2f7f3b7c073d8c',
    'governance':'0xcf81d69fed252f21bfd7661ff53868aa81b9ce1a4a1c89edbec9eaabffa7ad0a',
    'mandateRegistry':'0xe31e9d196bf5a37c328313f688b0d6eff881847e6c46437c1fc617faff8e80e3',
   },
  )
 def test_final_sdk_security_reconciliation(self):
  m=load_json(ROOT/'mappings/canonical-v3.json'); snapshot=load_json(ROOT/'interfaces/canonical-v3-interfaces.v1.json')
  self.assertEqual(m['sdkWriteMethods'],snapshot['sdkWriteMethods'])
  deployments={x['sdkName']:x for x in m['sdkDeployments']}
  self.assertIn('FLOURISHING_MISSION()',deployments['partnershipBond']['canonicalSignatures'])
  self.assertIn('FLOURISHING_NON_CONTROL_BOUNDARY()',deployments['partnershipBond']['canonicalSignatures'])
  governance=set(deployments['governance']['canonicalSignatures'])
  self.assertIn('canonicalRuntimeCodehash(address)',governance)
  self.assertIn('constructorPinnedPolicyTarget(address)',governance)
  self.assertIn('pinCanonicalAddress(address,bytes32)',governance)
  self.assertIn('setCallPolicy(address,bytes4,bool,uint96,bytes32)',governance)
  self.assertNotIn('setCallPolicy(address,bytes4,bool,uint96)',governance)
  writes=set(next(x for x in m['sdkWriteMethods'] if x['sdkName']=='governance')['canonicalSignatures'])
  self.assertEqual(writes,{'acceptGuardian()','cancel(uint256)','cancelGuardianRotation()','confirm(uint256)','execute(uint256)','guardianPause(address)','propose(address,uint256,bytes)','proposeGuardian(address)'})
  self.assertFalse(set(m['sdkWritePolicy']['excludedGovernanceConfigurationSignatures']).intersection(writes))
 def test_root_mit_license_is_bound(self):
  m=load_json(ROOT/'mappings/canonical-v3.json'); self.assertEqual(m['license']['spdx'],'MIT')
  self.assertEqual(hashlib.sha256((REPO/'LICENSE').read_bytes()).hexdigest(),m['license']['sha256'])
  self.assertIn('RESOLVED',(ROOT/'LICENSE-STATUS.md').read_text())
if __name__=='__main__': unittest.main()
