"""
Tests to validate the testing infrastructure works correctly.

Demonstrates:
- Test fixtures functionality
- Mock factories usage
- Test builders patterns
- Custom assertions
"""

import pytest
from pathlib import Path
from datetime import datetime, timezone

from tests.fixtures.markdown_samples import MarkdownDocumentBuilder, SAMPLE_SIMPLE_DOCUMENT
from tests.fixtures.api_responses import GiteaApiResponseBuilder, SAMPLE_ISSUE_RESPONSE
from tests.utils.test_builders import IssueBuilder, LabelBuilder, create_sample_issue
from tests.utils.mock_factories import MockRepositoryFactory, MockConfigFactory
from tests.utils.assertions import (
    assert_issue_equal, assert_file_exists, assert_directory_exists,
    assert_performance_within_bounds, validate_issue_data
)


class TestTestingInfrastructure:
    """Test that the testing infrastructure components work correctly."""

    def test_test_workspace_fixture(self, test_workspace):
        """Test that test workspace fixture creates proper isolated environment."""
        # Assert
        assert_directory_exists(test_workspace)
        assert_directory_exists(test_workspace / "documents")
        assert_directory_exists(test_workspace / "cache")
        assert_directory_exists(test_workspace / "workspaces")

        # Test creating files in workspace
        test_file = test_workspace / "test_file.txt"
        test_file.write_text("test content")
        assert_file_exists(test_file)

    def test_markdown_document_builder(self):
        """Test markdown document builder functionality."""
        # Act
        doc = (MarkdownDocumentBuilder()
               .with_metadata("title", "Test Doc")
               .with_metadata("author", "Test Author")
               .with_heading("Main Title")
               .with_paragraph("This is a test paragraph.")
               .with_list(["Item 1", "Item 2", "Item 3"])
               .with_code_block("print('hello')", "python")
               .build())

        # Assert
        assert "title: Test Doc" in doc
        assert "author: Test Author" in doc
        assert "# Main Title" in doc
        assert "This is a test paragraph." in doc
        assert "- Item 1" in doc
        assert "```python" in doc
        assert "print('hello')" in doc

    def test_gitea_api_response_builder(self):
        """Test Gitea API response builder functionality."""
        # Act
        response = (GiteaApiResponseBuilder()
                   .with_number(42)
                   .with_title("Test Issue")
                   .with_labels("bug", "priority:high")
                   .with_milestone("Version 1.0")
                   .build())

        # Assert
        assert response["number"] == 42
        assert response["title"] == "Test Issue"
        assert len(response["labels"]) == 2
        assert response["labels"][0]["name"] == "bug"
        assert response["labels"][1]["name"] == "priority:high"
        assert response["milestone"]["title"] == "Version 1.0"

    def test_issue_builder_functionality(self):
        """Test issue builder creates proper domain objects."""
        # Act
        issue = (IssueBuilder()
                .with_number(123)
                .with_title("Test Issue")
                .as_bug()
                .with_priority("high")
                .with_status("in-progress")
                .build())

        # Assert
        assert issue.number == 123
        assert issue.title == "Test Issue"
        assert len(issue.labels) == 3

        # Check label categorization
        categories = issue.categorize_labels()
        assert "bug" in categories.type_labels
        assert "priority:high" in categories.priority_labels
        assert "status:in-progress" in categories.state_labels

    def test_label_builder_functionality(self):
        """Test label builder creates correct labels."""
        # Act
        state_label = LabelBuilder().as_state_label("blocked").build()
        priority_label = LabelBuilder().as_priority_label("critical").build()
        type_label = LabelBuilder().as_type_label("bug").build()
        custom_label = LabelBuilder().with_custom_name("frontend").build()

        # Assert
        assert state_label.name == "status:blocked"
        assert state_label.is_state_label()

        assert priority_label.name == "priority:critical"
        assert priority_label.is_priority_label()

        assert type_label.name == "bug"
        assert type_label.is_type_label()

        assert custom_label.name == "frontend"
        assert not custom_label.is_state_label()
        assert not custom_label.is_priority_label()
        assert not custom_label.is_type_label()

    def test_mock_repository_factory(self):
        """Test mock repository factory creates proper mocks."""
        # Act
        issue_repo = MockRepositoryFactory.create_issue_repository()
        project_repo = MockRepositoryFactory.create_project_repository()
        document_repo = MockRepositoryFactory.create_document_repository()

        # Assert
        assert hasattr(issue_repo, 'get_issue')
        assert hasattr(issue_repo, 'create_issue')
        assert hasattr(issue_repo, 'update_issue')
        assert hasattr(issue_repo, 'list_issues')

        assert hasattr(project_repo, 'get_project')
        assert hasattr(project_repo, 'get_issue_project_info')

        assert hasattr(document_repo, 'store_document')
        assert hasattr(document_repo, 'search_content')

    def test_mock_config_factory(self):
        """Test mock configuration factory."""
        # Act
        config = MockConfigFactory.create_test_config({
            "custom_setting": "test_value",
            "workspace_dir": "/custom/workspace"
        })

        # Assert
        assert config.workspace_dir == "/custom/workspace"
        assert config.custom_setting == "test_value"
        assert config.gitea_url == "http://test-gitea.com"  # Default value
        assert config.log_level == "DEBUG"  # Default value

    def test_custom_assertions(self):
        """Test custom assertion functions."""
        # Arrange
        issue1 = create_sample_issue(1, "Test Issue")
        issue2 = create_sample_issue(1, "Test Issue")

        # Act & Assert - Should not raise
        assert_issue_equal(issue1, issue2, ignore_timestamps=True)

        # Test performance assertion
        execution_time = 0.05  # 50ms
        assert_performance_within_bounds(execution_time, 0.1, "test operation")

        # Test data validation
        valid_issue_data = {
            "number": 1,
            "title": "Valid Issue",
            "state": "open",
            "labels": [],
            "created_at": "2025-01-01T00:00:00Z",
            "updated_at": "2025-01-01T00:00:00Z"
        }
        assert validate_issue_data(valid_issue_data) is True

        invalid_issue_data = {
            "number": -1,  # Invalid number
            "title": "",   # Empty title
            "state": "invalid_state",  # Invalid state
        }
        assert validate_issue_data(invalid_issue_data) is False

    def test_sample_constants(self):
        """Test that sample constants are properly formed."""
        # Test markdown samples
        assert len(SAMPLE_SIMPLE_DOCUMENT) > 0
        assert "# Simple Document" in SAMPLE_SIMPLE_DOCUMENT

        # Test API response samples
        assert SAMPLE_ISSUE_RESPONSE["number"] == 123
        assert SAMPLE_ISSUE_RESPONSE["title"] == "Sample Issue"
        assert len(SAMPLE_ISSUE_RESPONSE["labels"]) > 0

    def test_performance_timer_fixture(self, performance_timer):
        """Test performance timer fixture functionality."""
        # Act
        performance_timer.start()

        # Simulate some work
        import time
        time.sleep(0.01)  # 10ms

        performance_timer.stop()

        # Assert
        assert performance_timer.elapsed > 0
        assert performance_timer.elapsed < 0.1  # Should be much less than 100ms

    def test_test_config_fixture(self, test_config):
        """Test test configuration fixture."""
        # Assert
        assert "workspace_dir" in test_config
        assert "database_path" in test_config
        assert "gitea_url" in test_config
        assert test_config["gitea_url"] == "http://test-gitea.com"

    def test_sample_markdown_content_fixture(self, sample_markdown_content):
        """Test sample markdown content fixture."""
        # Assert
        assert "Test Document" in sample_markdown_content
        assert "title:" in sample_markdown_content  # Front matter
        assert "**bold**" in sample_markdown_content
        assert "```python" in sample_markdown_content

    def test_sample_issue_data_fixture(self, sample_issue_data):
        """Test sample issue data fixture."""
        # Assert
        assert sample_issue_data["number"] == 123
        assert sample_issue_data["title"] == "Test Issue"
        assert sample_issue_data["state"] == "open"
        assert len(sample_issue_data["labels"]) > 0

    def test_isolated_environment_fixture(self, isolated_environment):
        """Test isolated environment fixture."""
        # Assert
        assert "MARKITECT_WORKSPACE_DIR" in isolated_environment
        assert "MARKITECT_GITEA_URL" in isolated_environment
        assert isolated_environment["MARKITECT_GITEA_URL"] == "http://test-gitea.com"

    @pytest.mark.parametrize("priority,expected", [
        ("low", "Low"),
        ("medium", "Medium"),
        ("high", "High"),
        ("critical", "Critical")
    ])
    def test_parametrized_testing_works(self, priority, expected):
        """Test that parametrized testing works with our infrastructure."""
        # Act
        issue = (IssueBuilder()
                .with_number(1)
                .with_title("Priority Test")
                .with_priority(priority)
                .build())

        # Assert
        categories = issue.categorize_labels()
        priority_labels = categories.priority_labels
        assert len(priority_labels) == 1
        assert priority_labels[0] == f"priority:{priority}"

    def test_test_markers_work(self):
        """Test that our custom test markers work."""
        # This test validates that the marker configuration is working
        # The markers are defined in pytest.ini and should not cause warnings
        pass

    @pytest.mark.unit
    def test_unit_marker_works(self):
        """Test that unit marker works."""
        assert True

    @pytest.mark.performance
    def test_performance_marker_works(self, performance_timer):
        """Test that performance marker works."""
        performance_timer.start()
        # Simulate quick operation
        result = sum(range(100))
        performance_timer.stop()

        assert result == 4950  # Mathematical verification
        assert performance_timer.elapsed < 0.01  # Should be very fast