"""
Test docstring preservation.
Copyright (c) 2025-2026 Greg Smethells. All rights reserved.
See the accompanying AUTHORS file for a complete list of authors.
This file is subject to the terms and conditions defined in LICENSE.
"""

import tempfile
from pathlib import Path
from prism.config import BlankLineConfig
from prism.processor import FileProcessor


class TestDocstringPreservation:
  def testMultilineDocstringWithBlankLines(self):
    """Test that multiline docstrings with blank lines are preserved"""

    input_code = '''class AIService:
  """
  **DESIGN REFERENCE: Layer 0: Foundational Services - LLM Service**

  Encapsulates all interactions with the AI model (Gemini).
  This service provides AI-powered functionality for User Need determination, functional statement generation,
  and Design Input matching used by the Builder Service and other specialized services.

  Architecture: Layer 0 - Foundational Services
  """

  def __init__(self):
    pass
'''

    with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
      f.write(input_code)
      f.flush()

      changed = FileProcessor.processFile(Path(f.name), checkOnly=False, config=BlankLineConfig.fromDefaults())

      # Should not change - docstring should be preserved as-is
      assert not changed

      with open(f.name) as result_file:
        result = result_file.read()

      assert result == input_code

  def testSingleQuoteDocstring(self):
    """Test that single-quoted docstrings are preserved"""

    input_code = """def my_function():
  '''
  This is a docstring with single quotes.
  
  It has blank lines inside.
  '''
  return 42
"""

    with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
      f.write(input_code)
      f.flush()

      changed = FileProcessor.processFile(Path(f.name), checkOnly=False, config=BlankLineConfig.fromDefaults())

      # Should not change
      assert not changed

      with open(f.name) as result_file:
        result = result_file.read()

      assert result == input_code

  def testDocstringWithHashSymbol(self):
    """Test that # symbols inside docstrings are not treated as comments"""

    input_code = '''def parse_markdown():
  """
  Parse markdown with headers.
  
  # This is not a comment, it's part of the docstring
  ## This is also part of the docstring
  
  Returns parsed content.
  """
  pass
'''

    with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
      f.write(input_code)
      f.flush()

      changed = FileProcessor.processFile(Path(f.name), checkOnly=False, config=BlankLineConfig.fromDefaults())

      # Should not change
      assert not changed

      with open(f.name) as result_file:
        result = result_file.read()

      assert result == input_code

  def testNestedQuotesInDocstring(self):
    """Test docstrings containing nested quotes"""

    input_code = '''def example():
  """
  This docstring contains "quotes" and 'apostrophes'.
  
  It also has a code example:
      print("Hello, world!")
  
  And it's preserved correctly.
  """
  pass
'''

    with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
      f.write(input_code)
      f.flush()

      changed = FileProcessor.processFile(Path(f.name), checkOnly=False, config=BlankLineConfig.fromDefaults())

      # Should not change
      assert not changed

      with open(f.name) as result_file:
        result = result_file.read()

      assert result == input_code

  def testDocstringFollowedByCodeInFunctionBody(self):
    """Test that no blank line is added between docstring and code in function body"""

    input_code = '''def __init__(self):
  """Initialize the AI service."""
  try:
    self.client = None
  except Exception:
    pass
'''

    with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
      f.write(input_code)
      f.flush()

      changed = FileProcessor.processFile(Path(f.name), checkOnly=False, config=BlankLineConfig.fromDefaults())

      # Should not change - no blank line between docstring and code
      assert not changed

      with open(f.name) as result_file:
        result = result_file.read()

      assert result == input_code

  def testRegularStatementsInFunctionBody(self):
    """Test that regular statements in function body don't get unnecessary blank lines"""

    input_code = """def func():
  x = "not a docstring"
  y = 42
  return x + str(y)
"""

    with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
      f.write(input_code)
      f.flush()

      changed = FileProcessor.processFile(Path(f.name), checkOnly=False, config=BlankLineConfig.fromDefaults())

      # Should not change - no blank lines between regular statements
      assert not changed

      with open(f.name) as result_file:
        result = result_file.read()

      assert result == input_code
