"""
Tests for timestamp-based slug generation (ADR-062)

Tests the new generate_timestamp_slug() function introduced in v1.5.0
to replace content-based slug generation with timestamp-based slugs.
"""

import pytest
from datetime import datetime
from starpunk.slug_utils import generate_timestamp_slug


class TestTimestampSlugGeneration:
    """Test timestamp-based slug generation per ADR-062"""

    def test_basic_timestamp_slug_format(self):
        """Test that timestamp slug matches YYYYMMDDHHMMSS format"""
        fixed_time = datetime(2025, 12, 16, 14, 30, 52)
        slug = generate_timestamp_slug(fixed_time, set())
        assert slug == "20251216143052"

    def test_no_collision_returns_base_slug(self):
        """Test that when no collision exists, base slug is returned"""
        fixed_time = datetime(2025, 12, 16, 14, 30, 52)
        existing_slugs = {"some-other-slug", "20251216140000"}
        slug = generate_timestamp_slug(fixed_time, existing_slugs)
        assert slug == "20251216143052"

    def test_first_collision_gets_suffix_1(self):
        """Test that first collision gets -1 suffix per ADR-062"""
        fixed_time = datetime(2025, 12, 16, 14, 30, 52)
        existing_slugs = {"20251216143052"}
        slug = generate_timestamp_slug(fixed_time, existing_slugs)
        assert slug == "20251216143052-1"

    def test_second_collision_gets_suffix_2(self):
        """Test that second collision gets -2 suffix"""
        fixed_time = datetime(2025, 12, 16, 14, 30, 52)
        existing_slugs = {"20251216143052", "20251216143052-1"}
        slug = generate_timestamp_slug(fixed_time, existing_slugs)
        assert slug == "20251216143052-2"

    def test_sequential_suffixes_up_to_10(self):
        """Test sequential suffix generation up to -10"""
        fixed_time = datetime(2025, 12, 16, 14, 30, 52)
        base_slug = "20251216143052"

        # Create existing slugs from base to -9
        existing_slugs = {base_slug}
        existing_slugs.update(f"{base_slug}-{i}" for i in range(1, 10))

        slug = generate_timestamp_slug(fixed_time, existing_slugs)
        assert slug == "20251216143052-10"

    def test_uses_utcnow_when_no_timestamp_provided(self):
        """Test that function defaults to current UTC time"""
        slug = generate_timestamp_slug(None, set())
        # Should be 14 characters (YYYYMMDDHHMMSS)
        assert len(slug) == 14
        assert slug.isdigit()

    def test_empty_existing_slugs_set(self):
        """Test with explicitly empty set"""
        fixed_time = datetime(2025, 12, 16, 14, 30, 52)
        slug = generate_timestamp_slug(fixed_time, set())
        assert slug == "20251216143052"

    def test_none_existing_slugs_defaults_to_empty(self):
        """Test that None existing_slugs is handled as empty set"""
        fixed_time = datetime(2025, 12, 16, 14, 30, 52)
        slug = generate_timestamp_slug(fixed_time, None)
        assert slug == "20251216143052"

    def test_different_timestamps_produce_different_slugs(self):
        """Test that different timestamps produce different slugs"""
        time1 = datetime(2025, 12, 16, 14, 30, 52)
        time2 = datetime(2025, 12, 16, 14, 30, 53)

        slug1 = generate_timestamp_slug(time1, set())
        slug2 = generate_timestamp_slug(time2, set())

        assert slug1 != slug2
        assert slug1 == "20251216143052"
        assert slug2 == "20251216143053"

    def test_midnight_timestamp(self):
        """Test timestamp at midnight"""
        fixed_time = datetime(2025, 1, 1, 0, 0, 0)
        slug = generate_timestamp_slug(fixed_time, set())
        assert slug == "20250101000000"

    def test_end_of_day_timestamp(self):
        """Test timestamp at end of day"""
        fixed_time = datetime(2025, 12, 31, 23, 59, 59)
        slug = generate_timestamp_slug(fixed_time, set())
        assert slug == "20251231235959"

    def test_leap_year_timestamp(self):
        """Test timestamp on leap day"""
        fixed_time = datetime(2024, 2, 29, 12, 30, 45)
        slug = generate_timestamp_slug(fixed_time, set())
        assert slug == "20240229123045"

    def test_single_digit_month_and_day(self):
        """Test that single-digit months and days are zero-padded"""
        fixed_time = datetime(2025, 1, 5, 9, 5, 3)
        slug = generate_timestamp_slug(fixed_time, set())
        assert slug == "20250105090503"
        assert len(slug) == 14  # Ensure proper padding

    def test_collision_with_gap_in_sequence(self):
        """Test collision handling when there's a gap in sequence"""
        fixed_time = datetime(2025, 12, 16, 14, 30, 52)
        # Base exists, -1 exists, but -2 doesn't exist
        existing_slugs = {"20251216143052", "20251216143052-1", "20251216143052-3"}
        slug = generate_timestamp_slug(fixed_time, existing_slugs)
        # Should fill the gap and return -2
        assert slug == "20251216143052-2"


class TestTimestampSlugIntegration:
    """Test timestamp slug integration with note creation"""

    def test_create_note_generates_timestamp_slug(self, app):
        """Test that creating a note without custom slug generates timestamp"""
        from starpunk.notes import create_note
        import re

        with app.app_context():
            note = create_note("Test content for timestamp slug")

            # Should match timestamp pattern per ADR-062
            timestamp_pattern = re.compile(r'^\d{14}(-\d+)?$')
            assert timestamp_pattern.match(note.slug), \
                f"Slug '{note.slug}' does not match timestamp format"

    def test_create_multiple_notes_same_second(self, app):
        """Test creating multiple notes in same second gets sequential suffixes"""
        from starpunk.notes import create_note
        from datetime import datetime

        with app.app_context():
            fixed_time = datetime(2025, 12, 16, 14, 30, 52)

            # Create 3 notes at same timestamp
            note1 = create_note("First note", created_at=fixed_time)
            note2 = create_note("Second note", created_at=fixed_time)
            note3 = create_note("Third note", created_at=fixed_time)

            # Verify sequential slug assignment
            assert note1.slug == "20251216143052"
            assert note2.slug == "20251216143052-1"
            assert note3.slug == "20251216143052-2"

    def test_custom_slug_still_works(self, app):
        """Test that custom slugs via mp-slug still work unchanged"""
        from starpunk.notes import create_note

        with app.app_context():
            note = create_note("Test content", custom_slug="my-custom-slug")
            assert note.slug == "my-custom-slug"

    def test_timestamp_slug_does_not_collide_with_reserved(self, app):
        """Test that timestamp slugs cannot collide with reserved slugs"""
        from starpunk.slug_utils import RESERVED_SLUGS
        from datetime import datetime

        with app.app_context():
            # Timestamp slugs are all numeric, reserved slugs are alphabetic
            # So collision is impossible by construction
            fixed_time = datetime(2025, 12, 16, 14, 30, 52)
            slug = generate_timestamp_slug(fixed_time, set())

            # Verify slug is all numeric
            assert slug.replace('-', '').isdigit()

            # Verify it doesn't match any reserved slug
            assert slug not in RESERVED_SLUGS
