import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import test from "node:test";

const root = resolve(import.meta.dirname, "..");
const source = (program) =>
  readFileSync(resolve(root, "programs", program, "src", "lib.rs"), "utf8");

test("all fifteen native programs avoid unchecked increment and decrement operators", () => {
  const programs = [
    "ai_accountability_bonds",
    "ai_partnership_bonds",
    "anti_surveillance",
    "belief_attestation_verifier",
    "dilithium_attestor",
    "flourishing_metrics_oracle",
    "identity_registry",
    "mission_enforcement",
    "multisig_governance",
    "privacy_guarantees",
    "production_belief_verifier",
    "reputation_registry",
    "trust_data_bridge",
    "validation_registry",
    "vaultfire_adapter",
  ];

  for (const program of programs) {
    assert.doesNotMatch(source(program), /(?:\+=|-=)/, program);
  }
});

test("all global bootstraps fail closed without an approved source-backed authority design", () => {
  const programs = [
    "ai_accountability_bonds",
    "ai_partnership_bonds",
    "anti_surveillance",
    "belief_attestation_verifier",
    "dilithium_attestor",
    "flourishing_metrics_oracle",
    "identity_registry",
    "mission_enforcement",
    "multisig_governance",
    "privacy_guarantees",
    "production_belief_verifier",
    "reputation_registry",
    "trust_data_bridge",
    "validation_registry",
    "vaultfire_adapter",
  ];

  for (const program of programs) {
    assert.match(source(program), /let deployment_authorized = false;/, program);
    assert.match(source(program), /BootstrapDisabled/, program);
  }
});

test("accountability bonds use an initialized, program-owned vault with rent-safe accounting", () => {
  const code = source("ai_accountability_bonds");
  assert.match(code, /pub bond_vault: Account<'info, BondVault>/);
  assert.match(code, /init,[\s\S]*?space = BOND_VAULT_SPACE,[\s\S]*?seeds = \[b"vault", agent\.key\(\)\.as_ref\(\)\]/);
  assert.match(code, /constraint = bond\.vault == bond_vault\.key\(\) @ AccountabilityError::InvalidBondVault/);
  assert.match(code, /Rent::get\(\)\?\.minimum_balance\(BOND_VAULT_SPACE\)/);
  assert.match(code, /checked_withdrawal_totals\(state\.total_bonds, state\.total_staked, amount\)/);
  assert.match(code, /checked_stake_totals\(state\.total_bonds, state\.total_staked, amount\)/);
  assert.match(code, /total_bonds\.checked_sub\(1\)/);
  assert.match(code, /close = agent,\s*seeds = \[b"acc_bond"/);
  assert.match(code, /close = agent,\s*seeds = \[b"vault"/);
  assert.doesNotMatch(code, /UncheckedAccount/);
  assert.match(code, /err!\(AccountabilityError::SlashingUnavailable\)/);
});

test("partnership bonds require both independent participants and one canonical bond", () => {
  const code = source("ai_partnership_bonds");
  assert.match(code, /pub agent_a: Signer<'info>/);
  assert.match(code, /pub agent_b: Signer<'info>/);
  assert.match(code, /agent_a != agent_b, BondError::DuplicateParticipant/);
  assert.match(code, /agent_a\.to_bytes\(\) < agent_b\.to_bytes\(\)/);
  assert.match(code, /seeds = \[b"bond", bonds_state\.key\(\)\.as_ref\(\), agent_a\.key\(\)\.as_ref\(\), agent_b\.key\(\)\.as_ref\(\)\]/);
  assert.match(code, /constraint = bond\.state == bonds_state\.key\(\) @ BondError::InvalidBondState/);
  assert.match(code, /constraint = bond\.agent_a == agent_a\.key\(\) @ BondError::Unauthorized/);
  assert.match(code, /constraint = bond\.agent_b == agent_b\.key\(\) @ BondError::Unauthorized/);
  assert.match(code, /close = agent_a/);
});

test("identity deregistration is single-use so the aggregate count cannot be replay-decremented", () => {
  const code = source("identity_registry");
  assert.match(code, /require!\(agent\.active, IdentityError::AgentNotActive\);/);
  assert.match(code, /checked_sub\(1\)/);
  assert.match(code, /close = authority/);
  assert.match(code, /#\[account\(mut\)\]\s*pub authority: Signer<'info>/);
  assert.match(code, /AgentNotActive,/);
});

test("governance rejects duplicate weights, expires approvals, and only finalizes an approval record", () => {
  const code = source("multisig_governance");
  assert.match(code, /!has_duplicate_signers\(&signers\),\s*GovernanceError::DuplicateSigner/);
  assert.match(code, /expires_at > now, GovernanceError::InvalidExpiry/);
  assert.match(code, /MAX_PROPOSAL_LIFETIME_SECONDS/);
  assert.match(code, /pub fn finalize_proposal/);
  assert.doesNotMatch(code, /pub fn execute_proposal/);
  assert.match(code, /state\.signers\.contains\(&ctx\.accounts\.executor\.key\(\)\)/);
  assert.match(code, /seeds = \[b"proposal", multisig_state\.key\(\)\.as_ref\(\), proposal\.id\.to_le_bytes\(\)\.as_ref\(\)\]/);
  assert.match(code, /constraint = proposal\.multisig == multisig_state\.key\(\) @ GovernanceError::InvalidProposal/);
  assert.match(code, /close = proposer/);
  assert.match(code, /address = proposal\.proposer @ GovernanceError::InvalidProposer/);
  assert.match(code, /pub fn close_expired_proposal/);
  assert.match(code, /unix_timestamp > ctx\.accounts\.proposal\.expires_at/);
  assert.doesNotMatch(code, /invoke(?:_signed)?\s*\(/);
});

test("unimplemented bridge and ML-DSA trust paths fail closed instead of storing unauthenticated claims", () => {
  const bridge = source("trust_data_bridge");
  const dilithium = source("dilithium_attestor");
  assert.match(bridge, /err!\(BridgeError::AttestationVerificationUnavailable\)/);
  assert.match(dilithium, /err!\(DilithiumError::VerificationUnavailable\)/);
  assert.doesNotMatch(dilithium, /record\.signature_bytes = signature_bytes/);
  assert.doesNotMatch(bridge, /message\.payload = payload/);
});

test("user-controlled PDA seed inputs reject values longer than Solana's 32-byte seed limit", () => {
  const cases = [
    {
      program: "belief_attestation_verifier",
      constant: "MAX_BELIEF_KEY_SEED_BYTES",
      input: "belief_key",
    },
    {
      program: "production_belief_verifier",
      constant: "MAX_BELIEF_KEY_SEED_BYTES",
      input: "belief_key",
    },
    {
      program: "validation_registry",
      constant: "MAX_VALIDATION_TYPE_SEED_BYTES",
      input: "validation_type",
    },
    {
      program: "flourishing_metrics_oracle",
      constant: "MAX_METRIC_NAME_SEED_BYTES",
      input: "metric_name",
    },
  ];

  for (const { program, constant, input } of cases) {
    const code = source(program);
    assert.match(code, new RegExp(`const ${constant}: usize = 32;`), program);
    assert.match(
      code,
      new RegExp(`${input}\\.len\\(\\) <= ${constant}`),
      program,
    );
  }
});

test("mission, privacy, and flourishing telemetry retain the mission boundary", () => {
  const mission = source("mission_enforcement");
  const privacy = source("privacy_guarantees");
  const surveillance = source("anti_surveillance");
  const metrics = source("flourishing_metrics_oracle");

  assert.match(mission, /pub const MISSION_BOUNDARY: &str/);
  assert.match(mission, /mission_statement == MISSION_BOUNDARY/);
  assert.match(mission, /err!\(VaultfireError::MissionBoundaryImmutable\)/);
  assert.doesNotMatch(metrics, /pub observational_only: bool/);
  assert.match(
    metrics,
    /space = 8 \+ 32 \+ 4 \+ 64 \+ 8 \+ 4 \+ 256 \+ 8 \+ 4,/,
  );
  assert.match(metrics, /flourishing_metric_retains_the_v1_serialized_layout/);
  assert.match(metrics, /assert_eq!\(serialized\.len\(\), 380\);/);
  assert.doesNotMatch(metrics, /pub fn (?:withdraw|slash|resolve_dispute|set_eligibility|set_access)/);
  assert.doesNotMatch(metrics, /CpiContext|system_program::transfer/);
  assert.match(privacy, /commitment\.compliant = false;/);
  assert.match(privacy, /err!\(PrivacyError::ComplianceVerificationUnavailable\)/);
  assert.match(surveillance, /attestation\.compliant = false;/);
});

test("the source-only Anchor profile has no deployable localnet map, wallet, or test command", () => {
  const anchorToml = readFileSync(resolve(root, "Anchor.toml"), "utf8");
  assert.doesNotMatch(anchorToml, /\[programs\.localnet\]/);
  assert.doesNotMatch(anchorToml, /\[scripts\]/);
  assert.match(anchorToml, /wallet = "\.\/SOURCE_ONLY_WALLET_NOT_PROVIDED\.json"/);
  assert.equal(
    readFileSync(resolve(root, "package.json"), "utf8").includes('"test:readiness"'),
    true,
  );
});

test("claims and decisions fail closed without independent verification", () => {
  const validation = source("validation_registry");
  const adapter = source("vaultfire_adapter");
  const productionBeliefs = source("production_belief_verifier");

  assert.match(validation, /pub enum ValidationStatus\s*\{\s*Pending,\s*Approved,\s*Rejected,/s);
  assert.match(validation, /validation\.status == ValidationStatus::Pending/);
  assert.match(validation, /validation\.status = ValidationStatus::Approved;/);
  assert.match(validation, /validation\.status = ValidationStatus::Rejected;/);
  assert.doesNotMatch(adapter, /reputation_score|identity_verified/);
  assert.match(adapter, /seeds = \[b"profile", agent\.key\(\)\.as_ref\(\)\]/);
  assert.match(adapter, /has_one = agent/);
  assert.match(adapter, /pub agent: Signer<'info>/);
  assert.doesNotMatch(adapter, /has_one = authority/);
  assert.match(
    productionBeliefs,
    /pub struct RegisterAgent<'info> \{\s*#\[account\(\s*seeds = \[b"prod_verifier"\]/s,
  );
});

test("the V3 release record is source-only and cannot be mistaken for a deployment", () => {
  const release = JSON.parse(readFileSync(resolve(root, "V3_SECURITY_RELEASE.json"), "utf8"));
  const anchorToml = readFileSync(resolve(root, "Anchor.toml"), "utf8");
  const deployWrapper = readFileSync(resolve(root, "scripts", "deploy-blocked.mjs"), "utf8");

  assert.equal(release.status, "blocked");
  assert.equal(release.auditScopeCommit, null);
  assert.equal(release.candidateCommitEvidenceAvailable, false);
  assert.equal(release.committedCandidateRequiredForExecutableEvidence, true);
  assert.equal(release.dispositionManifestSha256, null);
  assert.equal(release.supportedSourceManifestSha256, null);
  assert.deepEqual(release.mainnetProgramIds, []);
  assert.deepEqual(release.deploymentEvidence, []);
  assert.equal(release.independentHumanAuditComplete, false);
  assert.doesNotMatch(anchorToml, /skip-lint\s*=\s*true/);
  assert.match(deployWrapper, /process\.exitCode = 1/);
});
