import pytest
from pathlib import Path
import tempfile
import os

from loops.system_prompt import SystemPrompt


@pytest.fixture
def fake_prompt_file():
    """Generate a temporary text file containing a system prompt."""
    with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as tmp_file:
        prompt_path = tmp_file.name
        tmp_file.write("You are a helpful AI assistant.")
        
    yield prompt_path
    
    # Cleanup
    if os.path.exists(prompt_path):
        os.unlink(prompt_path)


def test_read_returns_correct_structure(fake_prompt_file):
    """Test that read() returns the correct LangChain-compatible structure."""
    prompt = SystemPrompt(fake_prompt_file)
    result = prompt.read()
    
    # Check structure
    assert isinstance(result, dict)
    assert "type" in result
    assert "text" in result
    assert result["type"] == "text"
    assert isinstance(result["text"], str)


def test_read_returns_correct_content(fake_prompt_file):
    """Test that read() returns the correct file content."""
    prompt = SystemPrompt(fake_prompt_file)
    result = prompt.read()
    
    assert result["text"] == "You are a helpful AI assistant."


def test_read_with_multiline_content():
    """Test that read() correctly handles multiline text."""
    multiline_text = """You are a helpful AI assistant.
You should be polite and professional.
Always provide accurate information."""
    
    with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as tmp_file:
        prompt_path = tmp_file.name
        tmp_file.write(multiline_text)
    
    try:
        prompt = SystemPrompt(prompt_path)
        result = prompt.read()
        
        assert result["type"] == "text"
        assert result["text"] == multiline_text
    finally:
        if os.path.exists(prompt_path):
            os.unlink(prompt_path)


def test_read_nonexistent_file():
    """Test that read() returns empty string for non-existent files."""
    prompt = SystemPrompt("/nonexistent/path/to/prompt.txt")
    result = prompt.read()
    
    # Should return empty content instead of raising error
    assert result["type"] == "text"
    assert result["text"] == ""


def test_read_empty_file():
    """Test that read() handles empty files correctly."""
    with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as tmp_file:
        prompt_path = tmp_file.name
        # Don't write anything - empty file
    
    try:
        prompt = SystemPrompt(prompt_path)
        result = prompt.read()
        
        assert result["type"] == "text"
        assert result["text"] == ""
    finally:
        if os.path.exists(prompt_path):
            os.unlink(prompt_path)


def test_read_with_special_characters():
    """Test that read() correctly handles special characters."""
    special_text = "Hello! @#$%^&*() 你好 émojis: 🎉🚀"
    
    with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False, encoding='utf-8') as tmp_file:
        prompt_path = tmp_file.name
        tmp_file.write(special_text)
    
    try:
        prompt = SystemPrompt(prompt_path)
        result = prompt.read()
        
        assert result["type"] == "text"
        assert result["text"] == special_text
    finally:
        if os.path.exists(prompt_path):
            os.unlink(prompt_path)


def test_read_can_be_called_multiple_times(fake_prompt_file):
    """Test that read() can be called multiple times on the same instance."""
    prompt = SystemPrompt(fake_prompt_file)
    
    result1 = prompt.read()
    result2 = prompt.read()
    
    # Both calls should return the same data
    assert result1 == result2
    assert result1["text"] == result2["text"]


def test_read_with_different_file_paths():
    """Test that SystemPrompt works with different file paths."""
    text1 = "First prompt"
    text2 = "Second prompt"
    
    with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as tmp1:
        path1 = tmp1.name
        tmp1.write(text1)
    
    with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as tmp2:
        path2 = tmp2.name
        tmp2.write(text2)
    
    try:
        prompt1 = SystemPrompt(path1)
        prompt2 = SystemPrompt(path2)
        
        result1 = prompt1.read()
        result2 = prompt2.read()
        
        assert result1["text"] == text1
        assert result2["text"] == text2
        assert result1["text"] != result2["text"]
    finally:
        if os.path.exists(path1):
            os.unlink(path1)
        if os.path.exists(path2):
            os.unlink(path2)
