import unittest

from tools import vehicle_ingest_live_verify as live_verify


class VehicleIngestLiveVerifyTest(unittest.TestCase):
    def test_warns_when_formal_gb32960_platform_login_exists_without_vehicle_frames(self):
        checks = live_verify.evaluate_counts(
            {
                "jt808RawFrames": 36090,
                "jt808Locations": 8783,
                "gb32960PlatformLogins": 3,
                "gb32960VehicleRealtimeFrames": 0,
            },
            live_verify.Thresholds(
                min_jt808_raw_frames=1,
                min_jt808_locations=1,
                min_gb32960_platform_logins=1,
                min_gb32960_vehicle_realtime_frames=1,
                require_gb32960_vehicle_realtime=False,
            ),
        )

        by_name = {check.name: check for check in checks}

        self.assertEqual(live_verify.overall_status(checks), "warn")
        self.assertEqual(by_name["gb32960.vehicle_realtime"].status, "warn")
        self.assertIn("尚未收到正式车辆 0x02", by_name["gb32960.vehicle_realtime"].message)

    def test_fails_when_vehicle_frames_are_required_but_missing(self):
        checks = live_verify.evaluate_counts(
            {
                "jt808RawFrames": 10,
                "jt808Locations": 2,
                "gb32960PlatformLogins": 1,
                "gb32960VehicleRealtimeFrames": 0,
            },
            live_verify.Thresholds(require_gb32960_vehicle_realtime=True),
        )

        by_name = {check.name: check for check in checks}

        self.assertEqual(live_verify.overall_status(checks), "fail")
        self.assertEqual(by_name["gb32960.vehicle_realtime"].status, "fail")

    def test_gb32960_vehicle_realtime_sql_excludes_test_vins(self):
        sql = live_verify.gb32960_vehicle_realtime_count_sql(
            date_from="2026-06-29 00:00:00",
            date_to="2026-06-29 23:59:59",
        )

        self.assertIn("message_id = 2", sql)
        self.assertIn("vin <> ''", sql)
        self.assertIn("vin NOT LIKE 'LTEST%'", sql)
        self.assertIn("ts >= '2026-06-29 00:00:00'", sql)
        self.assertIn("ts <= '2026-06-29 23:59:59'", sql)

    def test_gb32960_peer_filter_treats_plain_ip_as_contains_pattern(self):
        sql = live_verify.gb32960_platform_login_count_sql(
            date_from="2026-06-29 00:00:00",
            date_to="2026-06-29 23:59:59",
            peer_like="115.29.187.205",
        )

        self.assertIn("peer LIKE '%115.29.187.205%'", sql)

    def test_gb32960_peer_filter_preserves_explicit_like_pattern(self):
        sql = live_verify.gb32960_platform_login_count_sql(
            date_from="2026-06-29 00:00:00",
            date_to="2026-06-29 23:59:59",
            peer_like="115.29.187.%",
        )

        self.assertIn("peer LIKE '115.29.187.%'", sql)

    def test_gb32960_command_counts_sql_uses_same_peer_filter(self):
        sql = live_verify.gb32960_command_count_sql(
            date_from="2026-06-29 00:00:00",
            date_to="2026-06-29 23:59:59",
            peer_like="115.29.187.205",
        )

        self.assertIn("protocol = 'GB32960'", sql)
        self.assertIn("peer LIKE '%115.29.187.205%'", sql)
        self.assertIn("GROUP BY message_id", sql)

    def test_gb32960_command_count_rows_include_command_names(self):
        response = {
            "code": 0,
            "data": [
                [2, 9],
                [5, 3],
            ],
        }

        rows = live_verify.command_count_rows(response)

        self.assertEqual(rows, [
            {"messageId": 2, "command": "REALTIME_REPORT", "count": 9},
            {"messageId": 5, "command": "PLATFORM_LOGIN", "count": 3},
        ])

    def test_gb32960_recent_frame_rows_surface_peer_and_raw_uri(self):
        response = {
            "code": 0,
            "data": [[
                "2026-06-29T12:26:21.385Z",
                5,
                "",
                "unknown:GB32960:f729d788b943630e",
                "115.29.187.205:59630",
                "archive://frame.bin",
            ]],
        }

        rows = live_verify.recent_frame_rows(response)

        self.assertEqual(rows, [{
            "ts": "2026-06-29T12:26:21.385Z",
            "messageId": 5,
            "command": "PLATFORM_LOGIN",
            "vin": "",
            "vehicleKey": "unknown:GB32960:f729d788b943630e",
            "peer": "115.29.187.205:59630",
            "rawUri": "archive://frame.bin",
        }])

    def test_jt808_location_sql_uses_current_vehicle_locations_stable_with_protocol_filter(self):
        sql = live_verify.jt808_location_count_sql(
            date_from="2026-06-29 00:00:00",
            date_to="2026-06-29 23:59:59",
        )

        self.assertEqual(
            sql,
            "SELECT COUNT(*) FROM vehicle_locations WHERE protocol = 'JT808' "
            "AND ts >= '2026-06-29 00:00:00' AND ts <= '2026-06-29 23:59:59'",
        )


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