import unittest

from omr_service.form_mapper import FormMapError, compile_omr_template, validate_definition


class FormMapperTests(unittest.TestCase):
    def base(self):
        return {
            "form_id": "BF000002",
            "page": {"width": 1560, "height": 2040},
            "bubble": {"width": 24, "height": 24},
            "preprocessors": [],
            "fields": [],
        }

    def test_optional_cones_are_separate_logical_fields(self):
        definition = self.base()
        definition["fields"] = [
            {
                "key": f"p1_cone_{i}",
                "type": "optional_single",
                "blank_value": "",
                "multi_mark": "review",
                "bubbles": [
                    {"value": "5", "center": [100 + i * 50, 400]},
                    {"value": "10", "center": [100 + i * 50, 440]},
                ],
            }
            for i in range(1, 6)
        ]
        template = compile_omr_template(definition)
        self.assertEqual(5, len(template["fieldBlocks"]))
        self.assertEqual(["5", "10"], template["fieldBlocks"]["p1_cone_3"]["bubbleValues"])

    def test_digit_requires_zero_through_nine(self):
        definition = self.base()
        definition["fields"] = [{
            "key": "competitor_id_1", "type": "digit",
            "bubbles": [{"value": str(i), "center": [100, 100 + i * 30]} for i in range(9)],
        }]
        with self.assertRaisesRegex(FormMapError, "0-9"):
            validate_definition(definition)

    def test_checkbox_must_be_one_bubble(self):
        definition = self.base()
        definition["fields"] = [{
            "key": "p1_stop", "type": "checkbox",
            "bubbles": [{"value": "-50", "center": [100, 100]}, {"value": "-50b", "center": [120, 100]}],
        }]
        with self.assertRaisesRegex(FormMapError, "exactly one"):
            validate_definition(definition)

    def test_irregular_bubbles_are_rejected_instead_of_guessed(self):
        definition = self.base()
        definition["fields"] = [{
            "key": "score", "type": "required_single",
            "bubbles": [
                {"value": "0", "center": [100, 100]},
                {"value": "10", "center": [140, 100]},
                {"value": "20", "center": [183, 102]},
            ],
        }]
        with self.assertRaisesRegex(FormMapError, "regular row/column"):
            compile_omr_template(definition)

    def test_control_requires_expected_value(self):
        definition = self.base()
        definition["fields"] = [{
            "key": "control_top", "type": "control",
            "bubbles": [{"value": "A", "center": [100, 100]}],
        }]
        with self.assertRaisesRegex(FormMapError, "expected"):
            validate_definition(definition)


if __name__ == "__main__":
    unittest.main()
