"""许可客户端基础测试（不依赖真实激活码）。"""

from __future__ import annotations

import json
import os
import sys
import tempfile
import unittest
from pathlib import Path
from unittest import mock

ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

from lib.license import license_lib as lic


class LicenseLibTests(unittest.TestCase):
    def setUp(self):
        self._td = tempfile.TemporaryDirectory()
        self.state = Path(self._td.name) / "license_state.json"
        self.env = {
            "LICENSE_API_URL": "https://sq.bz121.com",
            "LICENSE_CLIENT_KEY": "test-key",
            "LICENSE_STATE_PATH": str(self.state),
            "LICENSE_OFFLINE_GRACE_HOURS": "72",
        }
        self._patcher = mock.patch.dict(os.environ, self.env, clear=False)
        self._patcher.start()
        lic._env_loaded = True
        lic._cached_device_id = None

    def tearDown(self):
        self._patcher.stop()
        self._td.cleanup()

    def test_device_id_length(self):
        did = lic.get_device_id()
        self.assertGreaterEqual(len(did), 16)
        self.assertLessEqual(len(did), 64)
        self.assertEqual(did, lic.get_device_id())

    def test_not_activated(self):
        st = lic.get_license_status()
        self.assertFalse(st["valid"])
        self.assertEqual(st["reason"], "not_activated")

    def test_local_valid_within_grace(self):
        now = lic._now_ts()
        self.state.write_text(
            json.dumps(
                {
                    "subscription_id": "sub_test",
                    "expires_at": "2099-01-01T00:00:00+08:00",
                    "plan": "monthly",
                    "last_ok_at": now,
                    "last_validate_at": now,
                }
            ),
            encoding="utf-8",
        )
        st = lic.get_license_status(skip_remote=True)
        self.assertTrue(st["valid"])

    def test_redeem_posts_api(self):
        def fake_http(method, path, body):
            self.assertEqual(path, "/v1/redeem")
            self.assertIn("device_id", body)
            self.assertEqual(body["code"], "ABCD1234EFGH")
            return {
                "ok": True,
                "subscription_id": "sub1",
                "plan": "monthly",
                "expires_at": "2099-06-01T00:00:00+08:00",
                "message": "激活成功",
            }

        with mock.patch.object(lic, "_http_json", side_effect=fake_http):
            r = lic.redeem_code("abcd1234efgh")
        self.assertTrue(r["ok"])
        data = json.loads(self.state.read_text(encoding="utf-8"))
        self.assertEqual(data["subscription_id"], "sub1")


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