import importlib.util
import pathlib
import sys
import types
import unittest
from unittest.mock import patch


ROOT = pathlib.Path(__file__).parents[1]


class BeeOrderHistoryPersistenceTests(unittest.TestCase):
    def test_order_upsert_uses_stable_id_and_latest_status(self):
        module_path = ROOT / "beeDataHandler" / "beeDataHandler.py"
        saved_module = sys.modules.get("ConnectionPool")
        sys.modules["ConnectionPool"] = types.SimpleNamespace(ConnectionPool=object)
        try:
            spec = importlib.util.spec_from_file_location("bee_order_handler", module_path)
            handler = importlib.util.module_from_spec(spec)
            with patch("logging.basicConfig"):
                spec.loader.exec_module(handler)
        finally:
            if saved_module is None:
                del sys.modules["ConnectionPool"]
            else:
                sys.modules["ConnectionPool"] = saved_module

        class Cursor:
            def execute(self, query, params):
                self.query = query
                self.params = params

        class Connection:
            def __init__(self):
                self.cursor_value = Cursor()
                self.committed = False

            def cursor(self):
                return self.cursor_value

            def commit(self):
                self.committed = True

        class Pool:
            def __init__(self):
                self.connection = Connection()
                self.released = None

            def get_connection(self):
                return self.connection

            def release_connection(self, connection):
                self.released = connection

        pool = Pool()
        handler.upsert_order_to_db(pool, {
            "id": "996-1720000000000",
            "label": "grid_order-BTC-PERPETUAL-1",
            "side": 1,
            "test_id": 996,
            "instrument_id": 92,
            "amount": 1.25,
            "creation_timestamp": 1720000000,
            "price": 100000.0,
            "status": 1,
            "type": "take_market",
        })

        self.assertEqual("996-1720000000000", pool.connection.cursor_value.params[0])
        self.assertEqual(6, pool.connection.cursor_value.params[-1])
        self.assertIn("ON DUPLICATE KEY UPDATE", pool.connection.cursor_value.query)
        self.assertIn("`status` = VALUES(`status`)", pool.connection.cursor_value.query)
        self.assertTrue(pool.connection.committed)
        self.assertIs(pool.connection, pool.released)

    def test_listener_persists_order_events_idempotently(self):
        source = (ROOT / "beeDataHandler" / "beeDataHandler.py").read_text(
            encoding="utf-8"
        )
        self.assertIn("test.orders.*", source)
        self.assertIn("def upsert_order_to_db", source)
        self.assertIn("source_order_id", source)
        self.assertIn("ON DUPLICATE KEY UPDATE", source)

    def test_migration_adds_a_unique_external_order_identity(self):
        migration = (
            ROOT / "deploy" / "migrations" / "20260801_bee_order_history.sql"
        ).read_text(encoding="utf-8")
        self.assertIn("ADD COLUMN IF NOT EXISTS `source_order_id`", migration)
        self.assertIn(
            "UNIQUE INDEX IF NOT EXISTS `uq_bee_orders_source_order_id`",
            migration,
        )


if __name__ == "__main__":
    unittest.main()
