import copy
import json
from pathlib import Path
import subprocess
import sys
import tempfile
import unittest

SCRIPT = Path(__file__).with_name('ai_compare.py')

class BatchComparisonTests(unittest.TestCase):
    def fixture(self):
        names = {f'PILOT_AI_ENUM_{i}' for i in range(1, 18)} | {
            'PILOT_AI_SPORT_ALL_ALL', 'PILOT_AI_SPORT_ALL_1', 'PILOT_AI_SPORT_ALL_2',
            'PILOT_AI_SPORT_CATE', 'PILOT_AI_SPORT_GROUPED'}
        b = {name: {'http_status': 200, 'body': {'status': 200,
            'trace_id': '123456789abcd', 'data': {'values': [1, 2], 'money': '1.20'}}} for name in names}
        c = copy.deepcopy(b)
        for case in c.values():
            case['body']['trace_id'] = 'abcde12345678'
        return b, c

    def run_compare(self, b, c):
        with tempfile.TemporaryDirectory(prefix='cdx-contract-unit-') as directory:
            left, right = Path(directory) / 'b.json', Path(directory) / 'c.json'
            left.write_text(json.dumps(b))
            right.write_text(json.dumps(c))
            return subprocess.run([sys.executable, str(SCRIPT), str(left), str(right)], capture_output=True).returncode

    def test_valid_full_batch(self):
        self.assertEqual(self.run_compare(*self.fixture()), 0)

    def test_empty_batches_are_not_passes(self):
        self.assertNotEqual(self.run_compare({}, {}), 0)

    def test_both_missing_trace_rejected(self):
        b, c = self.fixture()
        for rows in (b, c):
            del rows['PILOT_AI_ENUM_1']['body']['trace_id']
        self.assertNotEqual(self.run_compare(b, c), 0)

    def test_numeric_string_difference_rejected(self):
        b, c = self.fixture()
        c['PILOT_AI_ENUM_1']['body']['data']['money'] = 1.20
        self.assertNotEqual(self.run_compare(b, c), 0)

    def test_array_reordering_rejected(self):
        b, c = self.fixture()
        c['PILOT_AI_ENUM_1']['body']['data']['values'] = [2, 1]
        self.assertNotEqual(self.run_compare(b, c), 0)

    def test_equal_failed_status_not_positive(self):
        b, c = self.fixture()
        for rows in (b, c):
            rows['PILOT_AI_ENUM_1']['http_status'] = 500
        self.assertNotEqual(self.run_compare(b, c), 0)

    def test_same_trace_rejected(self):
        b, c = self.fixture()
        c['PILOT_AI_ENUM_1']['body']['trace_id'] = b['PILOT_AI_ENUM_1']['body']['trace_id']
        self.assertNotEqual(self.run_compare(b, c), 0)

if __name__ == '__main__':
    unittest.main()
