import unittest

from h8536.lcd_text import analyze_lcd_text, lcd_text_comment_for_instruction
from h8536.model import Instruction
from h8536.rom import Rom


class LcdTextTest(unittest.TestCase):
    def test_finds_ff_terminated_menu_strings_and_raw_mov_xrefs(self):
        data = bytearray([0x00] * 0x2200)
        data[0x1000:0x100D] = b"OPERATION " + b"\xFF\xFF\xFF"
        data[0x100D:0x1013] = bytes.fromhex("58 0F FD 1E 00 1D")
        data[0x1030:0x103D] = b"  PAINT   " + b"\xFF\xFF\xFF"
        data[0x103D:0x1040] = bytes.fromhex("58 10 30")

        analysis = analyze_lcd_text(Rom(bytes(data)), search_terms=("CONNECT",))
        by_text = {item["trimmed"]: item for item in analysis["strings"]}

        self.assertIn("OPERATION", by_text)
        self.assertIn("PAINT", by_text)
        operation = by_text["OPERATION"]
        self.assertEqual(operation["kind"], "ff_terminated")
        self.assertEqual(operation["ff_terminators"], 3)
        self.assertEqual(operation["xrefs"][0]["kind"], "raw_mov_iw")
        self.assertEqual(operation["xrefs"][0]["target"], 0x0FFD)
        self.assertEqual(operation["xrefs"][0]["delta"], -3)
        self.assertEqual(operation["xrefs"][0]["following_bsr"]["target"], 0x1030)
        self.assertEqual(analysis["searches"][0]["status"], "not_found")

    def test_groups_nearby_strings_into_regions(self):
        data = bytearray([0x00] * 0x1400)
        data[0x1200:0x120D] = b"   LOCK   " + b"\xFF\xFF\xFF"
        data[0x1240:0x124D] = b"IRIS/M.BLK" + b"\xFF\xFF\xFF"

        analysis = analyze_lcd_text(Rom(bytes(data)))

        self.assertEqual(len(analysis["regions"]), 1)
        self.assertEqual(analysis["regions"][0]["count"], 2)
        self.assertIn("LOCK", analysis["regions"][0]["samples"])

    def test_decoded_operand_xref_comment(self):
        data = bytearray([0x00] * 0x1300)
        data[0x1100:0x110D] = b"CONNECT?  " + b"\xFF\xFF\xFF"
        instructions = {
            0x0100: Instruction(0x0100, b"\x58\x11\x00", "MOV:I.W", "#H'1100, R0"),
        }

        analysis = analyze_lcd_text(Rom(bytes(data)), instructions, search_terms=("CONNECT",))

        self.assertEqual(analysis["searches"][0]["status"], "found")
        self.assertIn("LCD text xref", lcd_text_comment_for_instruction(analysis, 0x0100))


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