#!/usr/bin/env python3
"""Mutation tests: evidence gates must not silently turn failures into a pass."""
import contextlib
import copy
import importlib.util
import io
import json
from pathlib import Path
import sys
import tempfile

here = Path(__file__).resolve().parent
spec = importlib.util.spec_from_file_location('article_compare', here / 'compare.py')
compare = importlib.util.module_from_spec(spec)
spec.loader.exec_module(compare)
b = json.loads((here / 'evidence-B.json').read_text())
c = json.loads((here / 'evidence-C.json').read_text())

def verdict(left, right):
    with tempfile.TemporaryDirectory(prefix='cdx-article-comparator-') as folder:
        bp, cp = Path(folder) / 'b.json', Path(folder) / 'c.json'
        bp.write_text(json.dumps(left, ensure_ascii=False))
        cp.write_text(json.dumps(right, ensure_ascii=False))
        old = sys.argv
        sys.argv = ['compare.py', str(bp), str(cp)]
        try:
            with contextlib.redirect_stdout(io.StringIO()):
                return compare.main() == 0
        except (AssertionError, KeyError, TypeError):
            return False
        finally:
            sys.argv = old

checks = 0
def expect(value, expected):
    global checks
    checks += 1
    assert value is expected, 'mutation assertion ' + str(checks)

expect(verdict(b, c), True)
empty_b, empty_c = copy.deepcopy(b), copy.deepcopy(c)
empty_b['cases'] = empty_c['cases'] = []
empty_b['case_count'] = empty_c['case_count'] = 0
expect(verdict(empty_b, empty_c), False)
typed = copy.deepcopy(c)
typed['cases'][4]['body']['data']['detail']['virtual_views'] = '17'
expect(verdict(b, typed), False)
reordered = copy.deepcopy(c)
reordered['cases'][7]['body']['data']['list']['data'].reverse()
expect(verdict(b, reordered), False)
counter = copy.deepcopy(c)
counter['counter_checks'][0]['after_actual_views'] = 4
expect(verdict(b, counter), False)
leak = copy.deepcopy(c)
leak['cleanup']['fresh_pdo_owned_rows']['upload_file'] = 1
expect(verdict(b, leak), False)
empty_object = copy.deepcopy(c)
empty_object['cases'][3]['raw_json_shape']['object']['data'] = {'object': {}}
expect(verdict(b, empty_object), False)
failed_http = copy.deepcopy(c)
failed_http['cases'][3]['http_status'] = 500
expect(verdict(b, failed_http), False)
truncated = copy.deepcopy(c)
truncated['diagnostics']['store_long_content']['source_bytes'] = 32767
expect(verdict(b, truncated), False)
print(json.dumps({'status': 'PASS', 'assertions': checks}))
