import json
import tempfile
import unittest
from pathlib import Path

from h8536.dataflow import analyze_dataflow
from h8536.model import Instruction
from h8536.render import format_listing, write_json
from h8536.rom import Rom
from h8536.symbols import discover_symbols


class RenderAnalysisIntegrationTest(unittest.TestCase):
    def test_listing_and_json_include_symbols_and_compact_dataflow(self):
        instructions = {
            0x0100: Instruction(0x0100, b"\x58\x12\x34", "MOV:I.W", "#H'1234, R0"),
            0x0103: Instruction(
                0x0103,
                b"\x1D\xF6\x80\x90",
                "MOV:G.W",
                "R0, @H'F680",
                references=[0xF680],
            ),
        }
        dataflow = analyze_dataflow(instructions)
        symbols = discover_symbols(instructions)
        rom = Rom(bytes([0xFF] * 0x200))

        listing = format_listing(
            Path("rom.bin"),
            rom,
            instructions,
            {},
            {},
            "min",
            traced=True,
            dataflow=dataflow,
            symbols=symbols,
        )

        self.assertIn("; Symbols", listing)
        self.assertIn("ram_F680", listing)
        self.assertIn("dataflow R0=H'1234", listing)

        with tempfile.TemporaryDirectory() as tmp:
            path = Path(tmp) / "out.json"
            write_json(path, instructions, {}, {}, dataflow=dataflow, symbols=symbols)
            payload = json.loads(path.read_text(encoding="utf-8"))

        self.assertEqual(payload["symbols"]["symbols"][0]["name"], "ram_F680")
        self.assertEqual(payload["instructions"][1]["references"][0]["symbol"], "ram_F680")
        dataflow_payload = payload["instructions"][0]["dataflow"]
        self.assertEqual(dataflow_payload["changes"][0]["name"], "R0")
        self.assertEqual(dataflow_payload["known_after"]["registers"]["R0"]["value"], 0x1234)
        self.assertNotIn("before", dataflow_payload)


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