#!/usr/bin/env python3
import copy
import json
import pathlib
import sys
import unittest
from verify import load, verify

class EvidenceGateTests(unittest.TestCase):
    def test_baseline(self):
        self.assertEqual(verify(B, C)['status'], 'pass')

def mutation(name, change):
    def test(self):
        b, c = copy.deepcopy(B), copy.deepcopy(C)
        change(b, c)
        with self.assertRaises((AssertionError, KeyError, TypeError)):
            verify(b, c)
    setattr(EvidenceGateTests, 'test_reject_'+name, test)

def set_response(c, case, fn):
    fn(c['responses'][case]['body'])

MUTATIONS = {
    'weight_float': lambda b,c: set_response(c,'HARDWARE4',lambda x:x['data'][0]['dishes'][0].__setitem__('weight',12.34)),
    'image_id_string': lambda b,c: set_response(c,'HARDWARE4',lambda x:x['data'][0].__setitem__('id',str(x['data'][0]['id']))),
    'empty_object_not_list': lambda b,c: set_response(c,'HARDWARE4',lambda x:x['data'][0]['dishes'].__setitem__(1,{})),
    'flag_integer': lambda b,c: set_response(c,'CHECK4',lambda x:x['data']['rows'][0].__setitem__('is_flag',1)),
    'flag_wrong': lambda b,c: set_response(c,'CHECK1',lambda x:x['data']['rows'][0].__setitem__('is_flag',True)),
    'boolean_message_string': lambda b,c: set_response(c,'HARDWARE4',lambda x:x.__setitem__('message','true')),
    'code_string': lambda b,c: set_response(c,'HARDWARE4',lambda x:x['data'][0]['dishes'][0].__setitem__('code','1')),
    'total_string': lambda b,c: set_response(c,'CHECK4',lambda x:x['data'].__setitem__('total','1')),
    'quote_loss': lambda b,c: set_response(c,'HARDWARE4',lambda x:x['data'][0]['dishes'][0].__setitem__('name','wrong')),
    'missing_case': lambda b,c: c['report']['cases'].pop(),
    'empty_positive': lambda b,c: set_response(c,'CHECK4',lambda x:x['data'].__setitem__('rows',[])),
    'http500': lambda b,c: c['report']['cases'][0].__setitem__('http_status',500),
    'not_source_pass': lambda b,c: c['report']['cases'][0].__setitem__('source_pass',False),
    'unrestored': lambda b,c: c['report'].__setitem__('fixture_restored',False),
    'update_wrong_owner': lambda b,c: c['report']['updates'][0].__setitem__('owned_pk',1),
    'http_dml': lambda b,c: c['report'].__setitem__('http_dml',1),
    'worker_remaining': lambda b,c: c['cleanup'].__setitem__('worker_state_exists',True),
    'cache_remaining': lambda b,c: c['cleanup'].__setitem__('private_cache_files_remaining',1),
    'natural_c_drift': lambda b,c: c['report'].__setitem__('natural_unchanged',False),
    'b_global_false_claim': lambda b,c: b['report'].__setitem__('global_natural_unchanged_proven',True),
    'b_consumed_drift': lambda b,c: b['report'].__setitem__('consumed_source_unchanged',False),
    'b_request_window_drift': lambda b,c: b['report']['cases'][0].__setitem__('consumed_relation_window_unchanged',False),
    'source_sha_drift': lambda b,c: c['report']['source_sha256'].__setitem__('application/p/logic/DateMenu.php','0'*64),
    'actor_changed': lambda b,c: c['report'].__setitem__('actor_unchanged',False),
    'restaurant_changed': lambda b,c: c['report'].__setitem__('restaurant_unchanged',False),
    'queue_enabled': lambda b,c: c['report']['boundary'].__setitem__('real_queue',True),
    'source_owner_changed': lambda b,c: c['source']['CHECK4']['own_rows']['staff'].__setitem__('create_by','NATURAL'),
    'guid_relation_changed': lambda b,c: c['source']['CHECK4']['own_rows']['staff_department'].__setitem__('staff_uuid','NATURAL'),
    'fatal_request': lambda b,c: next(x for x in c['report']['events'] if x['kind']=='request_end').__setitem__('fatal',True),
}
for name, fn in MUTATIONS.items():
    mutation(name, fn)

if __name__ == '__main__':
    if len(sys.argv) != 3:
        raise SystemExit('usage: test_verify.py B-evidence-directory C-evidence-directory')
    B,C = load(sys.argv[1]),load(sys.argv[2])
    unittest.main(argv=[sys.argv[0]])
