from django.test import TestCase

from apps.drama.models import GameEvent, record
from apps.epic.models import Room
from apps.lyric.models import User


BASE = "https://earthmanrpg.me"


class ToActivityTest(TestCase):

    def setUp(self):
        self.user = User.objects.create(email="actor@test.io", username="testactor")
        self.room = Room.objects.create(name="Test Room", owner=self.user)

    def _record(self, verb, **data):
        return record(self.room, verb, actor=self.user, **data)

    def test_slot_filled_returns_join_gate_activity(self):
        event = self._record(
            GameEvent.SLOT_FILLED,
            slot_number=1, token_type="coin",
            token_display="Coin", renewal_days=7,
        )
        activity = event.to_activity(BASE)
        self.assertIsNotNone(activity)
        self.assertEqual(activity["type"], "earthman:JoinGate")

    def test_role_selected_returns_select_role_activity(self):
        event = self._record(
            GameEvent.ROLE_SELECTED,
            role="PC", slot_number=1, role_display="Player",
        )
        activity = event.to_activity(BASE)
        self.assertIsNotNone(activity)
        self.assertEqual(activity["type"], "earthman:SelectRole")

    def test_room_created_returns_create_activity(self):
        event = self._record(GameEvent.ROOM_CREATED)
        activity = event.to_activity(BASE)
        self.assertIsNotNone(activity)
        self.assertEqual(activity["type"], "Create")

    def test_unsupported_verb_returns_none(self):
        event = self._record(GameEvent.INVITE_SENT)
        self.assertIsNone(event.to_activity(BASE))

    def test_activity_contains_actor_url(self):
        event = self._record(
            GameEvent.ROLE_SELECTED,
            role="PC", slot_number=1, role_display="Player",
        )
        activity = event.to_activity(BASE)
        self.assertIn(BASE, activity["actor"])

    def test_activity_contains_object_url(self):
        event = self._record(
            GameEvent.SLOT_FILLED,
            slot_number=1, token_type="coin",
            token_display="Coin", renewal_days=7,
        )
        activity = event.to_activity(BASE)
        self.assertIn(str(self.room.id), activity["object"])


class EnsureKeypairTest(TestCase):

    def test_ensure_keypair_populates_both_fields(self):
        user = User.objects.create(email="keys@test.io")
        self.assertEqual(user.ap_public_key, "")
        self.assertEqual(user.ap_private_key, "")
        user.ensure_keypair()
        self.assertTrue(user.ap_public_key.startswith("-----BEGIN PUBLIC KEY-----"))
        self.assertTrue(user.ap_private_key.startswith("-----BEGIN PRIVATE KEY-----"))

    def test_ensure_keypair_persists_to_db(self):
        user = User.objects.create(email="persist@test.io")
        user.ensure_keypair()
        refreshed = User.objects.get(pk=user.pk)
        self.assertTrue(refreshed.ap_public_key.startswith("-----BEGIN PUBLIC KEY-----"))

    def test_ensure_keypair_is_idempotent(self):
        user = User.objects.create(email="idem@test.io")
        user.ensure_keypair()
        original_pub = user.ap_public_key
        user.ensure_keypair()
        self.assertEqual(user.ap_public_key, original_pub)
