#!/usr/bin/env python3
"""性能快照与推荐规则测试"""

import unittest
from datetime import datetime
from pathlib import Path
from unittest.mock import patch
import sys

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

from db import HistoryDB
import server


class TestLatestSnapshot(unittest.TestCase):
    def test_save_status_also_updates_latest_snapshot(self):
        fetch_time = datetime(2026, 6, 26, 10, 30, 0)
        connector = {
            "connector_id": "DC-17",
            "connector_name": "17号枪",
            "type": "DC",
            "power": 20,
            "vendor": "nio",
            "state": {"type": "free", "desc": "空闲"},
            "idle_seconds": 120,
        }

        with patch("db.Database.executemany", return_value=1) as executemany:
            saved = HistoryDB.save_status("station-1", [connector], fetch_time)

        self.assertEqual(saved, 1)
        self.assertEqual(executemany.call_count, 2)
        latest_sql = executemany.call_args_list[1].args[0]
        self.assertIn("charger_latest_status", latest_sql)
        self.assertIn("ON DUPLICATE KEY UPDATE", latest_sql)


class TestStationResponseCaching(unittest.TestCase):
    def test_station_response_returns_304_when_etag_matches(self):
        data = {
            "group_id": "station-1",
            "fetch_timestamp": 1782441000,
            "connectors": [
                {
                    "connector_id": "DC-17",
                    "connector_name": "17号枪",
                    "type": "DC",
                    "vendor": "nio",
                    "state": {"type": "free"},
                    "idle_seconds": 120,
                }
            ],
        }
        etag = server.build_station_etag(data)

        with server.app.test_request_context(headers={"If-None-Match": etag}):
            response = server.make_station_response(data)

        self.assertEqual(response.status_code, 304)
        self.assertEqual(response.headers["ETag"], etag)


class TestRecommendationRules(unittest.TestCase):
    def test_recommends_going_now_for_matching_free_connector(self):
        station = {
            "connectors": [
                {
                    "connector_id": "DC-17",
                    "connector_name": "17号枪",
                    "type": "DC",
                    "vendor": "nio",
                    "power": 20,
                    "state": {"type": "free"},
                    "idle_seconds": 180,
                },
                {
                    "connector_id": "AC-02",
                    "connector_name": "2号桩",
                    "type": "AC",
                    "vendor": "gongniu",
                    "power": 7,
                    "state": {"type": "free"},
                    "idle_seconds": 180,
                },
            ]
        }

        recommendation = server.build_recommendation(
            station,
            {"charger_type": "DC", "vendor": "nio"},
        )

        self.assertEqual(recommendation["action"], "go_now")
        self.assertEqual(recommendation["wait_minutes"], 0)
        self.assertEqual(recommendation["best_connector"]["connector_name"], "17号枪")

    def test_recommends_waiting_for_nearest_dc_remaining_time(self):
        station = {
            "connectors": [
                {
                    "connector_id": "DC-16",
                    "connector_name": "16号枪",
                    "type": "DC",
                    "vendor": "nio",
                    "power": 20,
                    "state": {"type": "charging"},
                    "estimated_charging_ready_time": 24,
                },
                {
                    "connector_id": "DC-17",
                    "connector_name": "17号枪",
                    "type": "DC",
                    "vendor": "nio",
                    "power": 20,
                    "state": {"type": "charging"},
                    "estimated_charging_ready_time": 9,
                },
            ]
        }

        recommendation = server.build_recommendation(
            station,
            {"charger_type": "DC", "vendor": "nio"},
        )

        self.assertEqual(recommendation["action"], "wait")
        self.assertEqual(recommendation["wait_minutes"], 9)
        self.assertIn("9", recommendation["message"])


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