"""Unit tests for crawler_core.boss.sign — BossSign and helper functions.

All tests are pure function assertions: no HTTP, no network, no mocks.
"""
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))

import re
import pytest
from crawler_core.boss.sign import BossSign, _compute_checksum, _generate_uuid, _CHARS


class TestBossSignGenerateTraceid:
    def test_traceid_format(self):
        tid = BossSign.generate_traceid()
        assert re.match(r'^M-W[0-9a-f]{13}[0-9a-zA-Z]{6}[0-9a-zA-Z]{3}$', tid), \
            f"Traceid format wrong: {tid}"

    def test_traceid_length(self):
        tid = BossSign.generate_traceid()
        assert len(tid) == 25, f"Expected 25 chars, got {len(tid)}: {tid}"

    def test_traceid_custom_prefix(self):
        tid = BossSign.generate_traceid(prefix="X-Y")
        assert tid.startswith("X-Y"), f"Expected X-Y prefix, got: {tid}"

    def test_traceid_uniqueness(self):
        t1 = BossSign.generate_traceid()
        t2 = BossSign.generate_traceid()
        assert t1 != t2, "Two calls should return different traceids"

    def test_bosssign_init_defaults(self):
        sign = BossSign()
        assert sign.mpt == ""
        assert sign.wt2 == ""

    def test_bosssign_init_with_tokens(self):
        sign = BossSign(mpt="mpt_token", wt2="wt2_token")
        assert sign.mpt == "mpt_token"
        assert sign.wt2 == "wt2_token"


class TestComputeChecksum:
    def test_checksum_length(self):
        checksum = _compute_checksum("1234567890abc456789")  # 19 chars
        assert len(checksum) == 3, f"Expected 3 chars, got {len(checksum)}"

    def test_checksum_chars_in_base62(self):
        checksum = _compute_checksum("1234567890abc456789")
        for ch in checksum:
            assert ch in _CHARS, f"Char {ch!r} not in base62 set"

    def test_checksum_deterministic(self):
        uuid_str = "1234567890abc456789"
        c1 = _compute_checksum(uuid_str)
        c2 = _compute_checksum(uuid_str)
        assert c1 == c2, "Same input must produce same checksum"

    def test_checksum_differs_for_different_input(self):
        # Different inputs should (almost always) produce different checksums
        c1 = _compute_checksum("1234567890abc456789")
        c2 = _compute_checksum("9876543210xyz456789")
        # Not guaranteed to differ but extremely likely
        # We test at least that they are valid 3-char strings
        assert len(c1) == 3 and len(c2) == 3


class TestGenerateUuid:
    def test_generate_uuid_length(self):
        uuid = _generate_uuid()
        assert len(uuid) == 19, f"Expected 19 chars, got {len(uuid)}: {uuid}"

    def test_generate_uuid_hex_prefix(self):
        uuid = _generate_uuid()
        hex_part = uuid[:13]
        assert re.match(r'^[0-9a-f]{13}$', hex_part), \
            f"First 13 chars should be hex: {hex_part}"

    def test_generate_uuid_base62_suffix(self):
        uuid = _generate_uuid()
        rand_part = uuid[13:]
        for ch in rand_part:
            assert ch in _CHARS, f"Char {ch!r} in random suffix not in base62"
