"""Independent regression audit of Appendix BS; not the missing sighting verifier.

Python 3, standard library only. Run: python audit_bs.py
Optional: --source PATH checks the supplied draft's identity and ledger counts.
Optional: --output PATH saves a machine-readable result (never changes the draft).
Exact rational checks are finite computations; all-time arguments are in BS_AUDIT.md.
"""
from fractions import Fraction as F
from itertools import combinations, permutations
import argparse
import hashlib
import json
import math
from pathlib import Path
import unittest

SOURCE_SHA256 = "8932ff1185c821eba3fe63458d7cc7fef42724cfc80e3b110aab1566da55f489"
POINT_TETRA = [(0, 0, 0), (1, 0, 1), (0, 1, 1), (0, 0, 1)]
LINE_TETRA = [(0, 0, 0), (1, 0, 0), (0, 1, 1), (0, 0, 2)]


def sub(a, b):
    return tuple(x - y for x, y in zip(a, b))


def squared_distances(points):
    return tuple(sum(x*x for x in sub(a, b)) for a, b in combinations(points, 2))


def det(a):
    n = len(a)
    total = 0
    for p in permutations(range(n)):
        inversions = sum(p[i] > p[j] for i in range(n) for j in range(i+1, n))
        total += (-1)**inversions * math.prod(a[i][p[i]] for i in range(n))
    return total


def volume(points):
    """Signed edge determinant: six times the oriented geometric volume."""
    return det([sub(points[i], points[0]) for i in (1, 2, 3)])


def rotate(points, c, s):
    return [(x, y, z*c, z*s) for x, y, z in points]


def circle_samples():
    # Rational parameterization. Finite checkpoints, NOT a continuous-path proof.
    for k in range(41):
        t = F(k, 10)
        yield (1-t*t)/(1+t*t), 2*t/(1+t*t)
    yield F(-1), F(0)


def barycentric_lattice(vertices, resolution=8):
    for a in range(resolution+1):
        for b in range(resolution-a+1):
            for c in range(resolution-a-b+1):
                weights = (a, b, c, resolution-a-b-c)
                yield tuple(sum(F(w, resolution)*v[j] for w, v in zip(weights, vertices))
                            for j in range(3))


def five_point_path(c, s):
    return [(0, 0, 0), (1, 0, 0), (0, 1, 0), (2, 0, c), (0, 2, s)]


def poisson_tail(mean, threshold):
    return 1 - math.exp(-mean)*sum(mean**j/math.factorial(j) for j in range(threshold))


def numerical_summary():
    seconds = 1e8 * 365.25 * 86400
    exposure = 1e22 * seconds
    ee_loss = 1e-4
    return {
        "one_hidden_axis_point_slice_dimension": 0,
        "one_hidden_axis_line_slice_dimension": 1,
        "point_tetra_signed_edge_determinant_before": volume(POINT_TETRA),
        "point_tetra_signed_edge_determinant_after": volume([(x, y, -z) for x, y, z in POINT_TETRA]),
        "hypothetical_quartz_exposure_unit_seconds": exposure,
        "hypothetical_quartz_inverse_exposure_per_second": 1/exposure,
        "hypothetical_zero_event_poisson_95_rate_per_second": -math.log(.05)/exposure,
        "poisson_probability_at_least_10_if_expected_10": poisson_tail(10, 10),
        "mass_of_1e18_molecules_at_100_g_per_mol_micrograms": 1e18/6.02214076e23*100*1e6,
        "net_inversions_for_1e_minus_4_ee_loss_in_1e18": 1e18*ee_loss/2,
        "symmetric_rate_for_ee_loss_over_3e7_s": -math.log1p(-ee_loss)/(2*3e7),
        "numerical_limitations": "Illustrative stipulated models, not measured bounds or experimental power validation."
    }


class AuditBS(unittest.TestCase):
    def test_t1_gram_determinant_fixes_volume_magnitude(self):
        edges = [sub(POINT_TETRA[i], POINT_TETRA[0]) for i in (1, 2, 3)]
        gram = [[sum(x*y for x, y in zip(a, b)) for b in edges] for a in edges]
        self.assertEqual(det(gram), volume(POINT_TETRA)**2)
        self.assertGreater(det(gram), 0)

    def test_t2_rational_rotation_preserves_six_distances(self):
        initial = squared_distances(POINT_TETRA)
        for c, s in circle_samples():
            self.assertEqual(c*c+s*s, 1)
            self.assertEqual(squared_distances(rotate(POINT_TETRA, c, s)), initial)

    def test_t2_midpoint_is_proper_four_dimensional_rotation(self):
        matrix = [[1,0,0,0], [0,1,0,0], [0,0,0,-1], [0,0,1,0]]
        self.assertEqual(det(matrix), 1)

    def test_t2_final_configuration_is_mirror(self):
        final = rotate(POINT_TETRA, -1, 0)
        self.assertEqual(final, [(x,y,-z,0) for x,y,z in POINT_TETRA])
        self.assertEqual(volume([p[:3] for p in final]), -volume(POINT_TETRA))

    def test_bs9_point_slice_with_only_one_hidden_axis(self):
        self.assertEqual(volume(POINT_TETRA), 1)
        pts = list(barycentric_lattice(POINT_TETRA))
        self.assertEqual(len(pts), 165)
        for c, s in ((F(0), F(1)), (F(3,5), F(4,5))):
            visible = [p for p in rotate(pts,c,s) if p[3] == 0]
            self.assertEqual(visible, [(0,0,0,0)])

    def test_bs9_line_slice_with_only_one_hidden_axis(self):
        self.assertEqual(volume(LINE_TETRA), 2)
        visible = [p for p in rotate(list(barycentric_lattice(LINE_TETRA)),0,1) if p[3] == 0]
        self.assertEqual(len(visible), 9)
        self.assertTrue(all(p[1:] == (0,0,0) for p in visible))

    def test_slice_and_projection_are_different(self):
        projected = [p[:3] for p in rotate(POINT_TETRA,F(3,5),F(4,5))]
        self.assertEqual(volume(projected), F(3,5))
        # The exact slice for this same body/angle is a point, as above.

    def test_five_points_stay_chiral_without_collisions(self):
        for c, s in circle_samples():
            pts = five_point_path(c,s)
            self.assertEqual(len(set(pts)), 5)
            v1 = volume(pts[:4])
            v2 = volume([pts[i] for i in (0,1,2,4)])
            self.assertEqual(v1*v1 + v2*v2, 1)
        # Full affine span and fixed labels forbid an improper pointwise symmetry.

    def test_five_point_path_ends_at_mirror_but_is_not_rigid(self):
        initial = five_point_path(1,0)
        final = five_point_path(-1,0)
        self.assertEqual(final, [(x,y,-z) for x,y,z in initial])
        self.assertEqual(squared_distances(final), squared_distances(initial))
        self.assertNotEqual(squared_distances(five_point_path(0,1)), squared_distances(initial))

    def test_endpoint_sampling_does_not_certify_rigidity(self):
        initial = [(0,0,0),(1,0,0),(0,1,0),(0,0,1)]
        final = [(x,y,-z) for x,y,z in initial]
        midpoint = initial[:3] + [(0,0,0)]
        self.assertEqual(squared_distances(initial), squared_distances(final))
        self.assertNotEqual(squared_distances(initial), squared_distances(midpoint))

    def test_fixed_bond_lengths_do_not_fix_all_pairwise_distances(self):
        initial = [(0,0,0),(1,0,0),(0,1,0),(0,0,1)]
        for c, s in circle_samples():
            pts = initial[:3] + [(F(3,5)*s,F(4,5)*s,c)]
            self.assertEqual(len(set(pts)), 4)
            self.assertEqual([sum(v*v for v in p) for p in pts[1:]], [1,1,1])
        midpoint = initial[:3] + [(F(3,5),F(4,5),0)]
        self.assertNotEqual(squared_distances(initial), squared_distances(midpoint))

    def test_null_likelihood_with_zero_rate_has_no_radius_bound(self):
        # H-Inv permits Gamma_4=0 at every radius. Zero observed events fit each.
        for radius in (1e-30,1e-10,1,1e30):
            gamma = 0.0
            self.assertEqual(math.exp(-gamma*1e22*3e15), 1)

    def test_zero_event_poisson_bound_inverts_probability(self):
        exposure = 1e22*1e8*365.25*86400
        rate = -math.log(.05)/exposure
        self.assertAlmostEqual(math.exp(-rate*exposure), .05, places=14)
        self.assertAlmostEqual(rate*exposure, 2.995732273553991, places=14)

    def test_ten_expected_events_is_not_95_percent_power(self):
        self.assertAlmostEqual(poisson_tail(10,10), .5420702855281478, places=13)

    def test_enantiomeric_excess_factor_two(self):
        n = 10**18
        inversions = 5*10**13
        self.assertEqual(F(n-2*inversions,n), F(9999,10000))
        rate = -math.log1p(-1e-4)/(2*3e7)
        self.assertAlmostEqual(math.exp(-2*rate*3e7), .9999, places=14)

    def test_invariant_separation_implies_unreachability(self):
        # G acts by g.x=(x+2g) mod 6. Parity is invariant; condition 2 implies 1.
        for start in range(6):
            orbit = {(start+2*g)%6 for g in range(3)}
            for target in range(6):
                if target%2 != start%2:
                    self.assertNotIn(target, orbit)


def main():
    ap = argparse.ArgumentParser(description=__doc__)
    ap.add_argument('--source', type=Path)
    ap.add_argument('--output', type=Path)
    args = ap.parse_args()
    provenance = {"expected_draft_sha256": SOURCE_SHA256, "source_checked": False}
    if args.source:
        raw = args.source.read_bytes()
        actual = hashlib.sha256(raw).hexdigest()
        if actual != SOURCE_SHA256:
            raise SystemExit('Draft digest mismatch; no source-specific verification claimed.')
        rows = raw.decode('utf-8').split('**Ledger.** Seventeen')[1].split('**Result.**')[0]
        counts = {kind: rows.count('| '+kind+' |') for kind in
                  ('deformation route','law not object','developmental origin','null bound')}
        if counts != {'deformation route':6,'law not object':5,'developmental origin':3,'null bound':3}:
            raise SystemExit('Unexpected ledger counts.')
        provenance.update(source_checked=True, sha256=actual, manuscript_ledger_counts=counts,
                          ledger_scope='Text tally only; not verification of phenomena or of missing source code.')
    result = unittest.TextTestRunner(verbosity=2).run(unittest.defaultTestLoader.loadTestsFromTestCase(AuditBS))
    record = {
        'artifact':'Independent Appendix BS audit, not dimensional_verifier.py',
        'evidence_class':'exact finite rational tests and stipulated statistical calculations; no physical experiment',
        'provenance':provenance,
        'tests':{'run':result.testsRun,'failures':len(result.failures),'errors':len(result.errors),'passed':result.wasSuccessful()},
        'results':numerical_summary(),
    }
    if args.output:
        if args.output.exists():
            raise SystemExit('Refusing to overwrite an existing result; select a new output path.')
        args.output.write_text(json.dumps(record,indent=2)+'\n', encoding='utf-8')
    print(json.dumps(record,indent=2))
    raise SystemExit(0 if result.wasSuccessful() else 1)


if __name__ == '__main__':
    main()
