"""Tests for the UserToken model."""

from datetime import timedelta

from django.contrib.auth import get_user_model
from django.test import TestCase
from django.utils import timezone

from mcp_server.models import UserToken, hash_token

User = get_user_model()


class UserTokenModelTest(TestCase):
    def setUp(self):
        self.user = User.objects.create_user(
            username="alice", email="alice@example.com", password="pw"
        )

    def test_create_token_returns_plaintext_and_stores_hash(self):
        token, plaintext = UserToken.objects.create_token(user=self.user, name="t")
        self.assertTrue(plaintext)
        self.assertGreater(len(plaintext), 20)
        # Database stores hash, not plaintext
        self.assertEqual(len(token.token_hash), 64)
        self.assertNotEqual(token.token_hash, plaintext)
        self.assertEqual(token.token_hash, hash_token(plaintext))

    def test_token_hash_never_equals_plaintext(self):
        # Regression guard: if anyone ever wires plaintext back into token_hash,
        # this fails.
        token, plaintext = UserToken.objects.create_token(user=self.user, name="t")
        self.assertNotIn(plaintext, token.token_hash)

    def test_active_token_is_valid(self):
        token, _ = UserToken.objects.create_token(user=self.user, name="t")
        self.assertTrue(token.is_valid)

    def test_inactive_token_not_valid(self):
        token, _ = UserToken.objects.create_token(user=self.user, name="t")
        token.is_active = False
        token.save()
        self.assertFalse(token.is_valid)

    def test_expired_token_not_valid(self):
        token, _ = UserToken.objects.create_token(
            user=self.user,
            name="t",
            expires_at=timezone.now() - timedelta(hours=1),
        )
        self.assertFalse(token.is_valid)

    def test_unrestricted_permits_all(self):
        token, _ = UserToken.objects.create_token(user=self.user, name="t")
        self.assertTrue(token.can_use_tool("anything"))

    def test_tool_whitelist(self):
        token, _ = UserToken.objects.create_token(
            user=self.user, name="t", allowed_tools=["search"]
        )
        self.assertTrue(token.can_use_tool("search"))
        self.assertFalse(token.can_use_tool("get_chunk"))

    def test_record_usage(self):
        token, _ = UserToken.objects.create_token(user=self.user, name="t")
        self.assertIsNone(token.last_used_at)
        token.record_usage()
        token.refresh_from_db()
        self.assertIsNotNone(token.last_used_at)

    def test_masked_token_is_hash_prefix(self):
        token, plaintext = UserToken.objects.create_token(user=self.user, name="t")
        masked = token.get_masked_token()
        self.assertTrue(masked.startswith("tok_…"))
        self.assertIn(token.token_hash[:8], masked)
        # Plaintext must never leak through the masked display
        self.assertNotIn(plaintext, masked)
