"""
Tests for public routes (homepage, note permalinks)

Tests cover:
- Homepage rendering with notes list
- Note permalink rendering
- 404 behavior for missing/unpublished notes
- Microformats2 markup
- Flash message display
- Error page rendering
"""

import pytest
from starpunk import create_app
from starpunk.notes import create_note


@pytest.fixture
def app(tmp_path):
    """Create test application with dev mode disabled"""
    # Create test-specific data directory
    test_data_dir = tmp_path / "data"
    test_data_dir.mkdir(parents=True, exist_ok=True)

    test_config = {
        "TESTING": True,
        "DATABASE_PATH": test_data_dir / "starpunk.db",
        "DATA_PATH": test_data_dir,
        "NOTES_PATH": test_data_dir / "notes",
        "SESSION_SECRET": "test-secret-key-for-testing-only",
        "ADMIN_ME": "https://test.example.com",
        "SITE_URL": "http://localhost:5000",
        "DEV_MODE": False,
    }
    app = create_app(config=test_config)
    yield app


@pytest.fixture
def client(app):
    """Test client for making requests"""
    return app.test_client()


@pytest.fixture
def sample_notes(app):
    """Create sample notes for testing"""
    with app.app_context():
        notes = []
        for i in range(5):
            note = create_note(
                content=f"# Test Note {i}\n\nThis is test note number {i}.",
                published=(i % 2 == 0),  # Even notes published, odd are drafts
            )
            notes.append(note)
        return notes


class TestHomepage:
    """Test homepage route (/)"""

    def test_homepage_renders(self, client):
        """Test homepage renders successfully"""
        response = client.get("/")
        assert response.status_code == 200
        assert b"StarPunk" in response.data

    def test_homepage_shows_published_notes(self, client, sample_notes):
        """Test homepage shows only published notes"""
        response = client.get("/")
        assert response.status_code == 200

        # Published notes should appear (notes 0, 2, 4)
        assert b"Test Note 0" in response.data
        assert b"Test Note 2" in response.data
        assert b"Test Note 4" in response.data

        # Draft notes should not appear (notes 1, 3)
        assert b"Test Note 1" not in response.data
        assert b"Test Note 3" not in response.data

    def test_homepage_empty_state(self, client):
        """Test homepage with no notes"""
        response = client.get("/")
        assert response.status_code == 200
        # Should have some message about no notes
        assert b"No notes" in response.data or b"Welcome" in response.data

    def test_homepage_has_feed_link(self, client):
        """Test homepage has RSS feed link"""
        response = client.get("/")
        assert response.status_code == 200
        assert b"feed.xml" in response.data or b"RSS" in response.data

    def test_homepage_has_h_feed_microformat(self, client, sample_notes):
        """Test homepage has h-feed microformat"""
        response = client.get("/")
        assert response.status_code == 200
        assert b"h-feed" in response.data

    def test_homepage_notes_have_h_entry(self, client, sample_notes):
        """Test notes on homepage have h-entry microformat"""
        response = client.get("/")
        assert response.status_code == 200
        assert b"h-entry" in response.data


class TestNotePermalink:
    """Test individual note permalink route (/note/<slug>)"""

    def test_published_note_renders(self, client, sample_notes):
        """Test published note permalink renders"""
        # Get a published note (note 0)
        with client.application.app_context():
            from starpunk.notes import list_notes

            notes = list_notes(published_only=True)
            assert len(notes) > 0
            slug = notes[0].slug

        response = client.get(f"/note/{slug}")
        assert response.status_code == 200
        assert b"Test Note" in response.data

    def test_note_has_full_content(self, client, sample_notes):
        """Test note page shows full content"""
        with client.application.app_context():
            from starpunk.notes import list_notes

            notes = list_notes(published_only=True)
            slug = notes[0].slug

        response = client.get(f"/note/{slug}")
        assert response.status_code == 200
        assert b"test note number" in response.data

    def test_note_has_h_entry_microformat(self, client, sample_notes):
        """Test note page has h-entry microformat"""
        with client.application.app_context():
            from starpunk.notes import list_notes

            notes = list_notes(published_only=True)
            slug = notes[0].slug

        response = client.get(f"/note/{slug}")
        assert response.status_code == 200
        assert b"h-entry" in response.data
        assert b"e-content" in response.data
        assert b"dt-published" in response.data

    def test_note_has_permalink_url(self, client, sample_notes):
        """Test note page has permalink URL"""
        with client.application.app_context():
            from starpunk.notes import list_notes

            notes = list_notes(published_only=True)
            slug = notes[0].slug

        response = client.get(f"/note/{slug}")
        assert response.status_code == 200
        assert b"u-url" in response.data

    def test_draft_note_returns_404(self, client, sample_notes):
        """Test draft note returns 404"""
        # Get a draft note (note 1)
        with client.application.app_context():
            from starpunk.notes import list_notes

            # Get all notes, then filter to drafts
            all_notes = list_notes()
            draft_notes = [n for n in all_notes if not n.published]
            assert len(draft_notes) > 0
            slug = draft_notes[0].slug

        response = client.get(f"/note/{slug}")
        assert response.status_code == 404

    def test_missing_note_returns_404(self, client):
        """Test missing note returns 404"""
        response = client.get("/note/nonexistent-slug")
        assert response.status_code == 404

    def test_note_has_back_link(self, client, sample_notes):
        """Test note page has link back to homepage"""
        with client.application.app_context():
            from starpunk.notes import list_notes

            notes = list_notes(published_only=True)
            slug = notes[0].slug

        response = client.get(f"/note/{slug}")
        assert response.status_code == 200
        # Should have a link to home
        assert b'href="/"' in response.data


class TestFlashMessages:
    """Test flash message display"""

    def test_flash_messages_display(self, client):
        """Test flash messages are displayed"""
        with client.session_transaction() as session:
            session["_flashes"] = [("success", "Test message")]

        response = client.get("/")
        assert response.status_code == 200
        assert b"Test message" in response.data

    def test_flash_message_categories(self, client):
        """Test different flash message categories"""
        categories = ["success", "error", "warning", "info"]

        for category in categories:
            with client.session_transaction() as session:
                session["_flashes"] = [(category, f"{category} message")]

            response = client.get("/")
            assert response.status_code == 200
            assert f"{category} message".encode() in response.data


class TestErrorPages:
    """Test error page rendering"""

    def test_404_page_renders(self, client):
        """Test 404 error page"""
        response = client.get("/nonexistent-page")
        assert response.status_code == 404
        assert b"404" in response.data or b"Not Found" in response.data

    def test_404_has_home_link(self, client):
        """Test 404 page has link to homepage"""
        response = client.get("/nonexistent-page")
        assert response.status_code == 404
        assert b'href="/"' in response.data


class TestDevModeIndicator:
    """Test dev mode warning display"""

    def test_dev_mode_warning_not_shown_in_production(self, client):
        """Test dev mode warning not shown when DEV_MODE=false"""
        response = client.get("/")
        assert response.status_code == 200
        assert b"DEVELOPMENT MODE" not in response.data

    def test_dev_mode_warning_shown_when_enabled(self, tmp_path):
        """Test dev mode warning shown when DEV_MODE=true"""
        test_data_dir = tmp_path / "dev_data"
        test_data_dir.mkdir(parents=True, exist_ok=True)

        test_config = {
            "TESTING": True,
            "DATABASE_PATH": test_data_dir / "starpunk.db",
            "DATA_PATH": test_data_dir,
            "NOTES_PATH": test_data_dir / "notes",
            "SESSION_SECRET": "test-secret",
            "SITE_URL": "http://localhost:5000",
            "DEV_MODE": True,
            "DEV_ADMIN_ME": "https://dev.example.com",
        }
        app = create_app(config=test_config)

        client = app.test_client()
        response = client.get("/")
        assert response.status_code == 200
        assert b"DEVELOPMENT MODE" in response.data or b"DEV MODE" in response.data


class TestVersionDisplay:
    """Test version number display"""

    def test_version_in_footer(self, client):
        """Test version number appears in footer"""
        response = client.get("/")
        assert response.status_code == 200
        assert b"0.5.0" in response.data or b"StarPunk v" in response.data


# OAuth metadata endpoint tests removed in Phase 1 of IndieAuth server removal
# The /.well-known/oauth-authorization-server endpoint was removed as part of
# removing the built-in IndieAuth authorization server functionality.
# See: docs/architecture/indieauth-removal-phases.md
