#!/usr/bin/env python3

from __future__ import print_function

import json
import os
import subprocess
import sys
import threading
import unittest
from http.server import BaseHTTPRequestHandler, HTTPServer
from pathlib import Path
from urllib.parse import parse_qs, urlparse


VIN = "LB9A32A21R0LS1464"
DENIED_VIN = "LA9935J21F0YWT578"


class Handler(BaseHTTPRequestHandler):
    def log_message(self, _format, *_args):
        pass

    def envelope(self, data, status=200):
        body = json.dumps({"data": data, "traceId": "test", "timestamp": 1}).encode("utf-8")
        self.send_response(status)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def do_POST(self):
        if self.path == "/api/v2/auth/login":
            self.envelope({"accessToken": "customer-token", "expiresAt": "2026-07-17T00:00:00+08:00", "session": {}})
            return
        if self.path == "/api/v2/auth/logout":
            self.envelope({"loggedOut": True})
            return
        self.envelope({}, 404)

    def do_GET(self):
        parsed = urlparse(self.path)
        values = parse_qs(parsed.query)
        if parsed.path == "/api/v2/session":
            self.envelope({"name": "客户验收", "role": "customer", "authMode": "enforce", "menuKeys": ["monitor", "vehicles", "tracks", "statistics"], "vehicleCount": 1})
        elif parsed.path == "/api/realtime/vehicles":
            self.envelope({"items": [{"vin": VIN, "plate": "粤AGR6863", "sourceCount": 2, "online": True, "locationAvailable": True}], "total": 1, "limit": 100, "offset": 0})
        elif parsed.path == "/api/vehicle-service" and values.get("keyword") == [VIN]:
            self.envelope({"lookupResolved": True, "vin": VIN})
        elif parsed.path == "/api/vehicle-service" and values.get("keyword") == [DENIED_VIN]:
            self.envelope({"lookupResolved": False, "vin": ""})
        elif parsed.path == "/api/v2/tracks":
            self.envelope({"vin": VIN, "points": [{"longitude": 113.1, "latitude": 23.1}, {"longitude": 113.2, "latitude": 23.2}]})
        elif parsed.path == "/api/v2/statistics/mileage":
            self.envelope({"vehicleCount": 1, "recordCount": 1})
        elif parsed.path in ("/monitor", "/vehicles/" + VIN, "/tracks", "/statistics"):
            body = "羚牛车辆数据中台".encode("utf-8")
            self.send_response(200)
            self.send_header("Content-Type", "text/html; charset=utf-8")
            self.send_header("Content-Length", str(len(body)))
            self.end_headers()
            self.wfile.write(body)
        else:
            self.envelope({}, 404)


class CustomerDemoGateTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.server = HTTPServer(("127.0.0.1", 0), Handler)
        cls.thread = threading.Thread(target=cls.server.serve_forever)
        cls.thread.daemon = True
        cls.thread.start()

    @classmethod
    def tearDownClass(cls):
        cls.server.shutdown()
        cls.thread.join()

    def test_complete_customer_demo_gate(self):
        script = str(Path(__file__).with_name("verify-customer-demo.py"))
        environment = dict(os.environ)
        environment["DEMO_PASSWORD"] = "not-persisted"
        result = subprocess.run([
            sys.executable, script,
            "--base-url", "http://127.0.0.1:{0}".format(self.server.server_port),
            "--username", "customer-demo",
            "--expected-vins", VIN,
            "--denied-vin", DENIED_VIN,
            "--multi-source-vin", VIN,
            "--track-vin", VIN,
            "--track-from", "2026-07-16T17:00:00+08:00",
            "--track-to", "2026-07-16T18:00:00+08:00",
            "--mileage-from", "2026-07-17",
            "--mileage-to", "2026-07-17"
        ], env=environment, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
        self.assertEqual(result.returncode, 0, result.stderr)
        self.assertIn("customer_demo_gate=ok", result.stdout)
        self.assertIn("vehicles=1", result.stdout)
        self.assertIn("samples=1 track=1 mileage=1 denied=1", result.stdout)


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