import unittest
from unittest.mock import patch, mock_open
from io import StringIO

from core.rwl.story_parser import StoryParser  # Assuming story_parser.py is in core.rwl

class TestStoryParser(unittest.TestCase):

    def setUp(self):
        self.parser = StoryParser()

    def test_parse_empty_file(self):
        data = ""
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [])

    def test_parse_single_story(self):
        data = "US-001: As a user, I want to log in."
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [{"id": "US-001", "text": "As a user, I want to log in."}])

    def test_parse_multiple_stories(self):
        data = "US-001: As a user, I want to log in.\nUS-002: As a user, I want to log out."
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [
            {"id": "US-001", "text": "As a user, I want to log in."},
            {"id": "US-002", "text": "As a user, I want to log out."}
        ])

    def test_parse_story_with_newline(self):
        data = "US-001: As a user,\nI want to log in."
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [{"id": "US-001", "text": "As a user,\nI want to log in."}])

    def test_parse_story_with_leading_and_trailing_whitespace(self):
        data = "  US-001:  As a user, I want to log in.  "
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [{"id": "US-001", "text": "As a user, I want to log in."}])

    def test_parse_story_with_special_characters(self):
        data = "US-001: As a user, I want to log in with @#$%^&*()_+=-`~[]\{}|;':\",./<>?"
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [{"id": "US-001", "text": "As a user, I want to log in with @#$%^&*()_+=-`~[]\{}|;':\",./<>?"}])

    def test_parse_story_with_no_id(self):
        data = ": As a user, I want to log in." # Intentionally missing ID prefix
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [])  # Should ignore or return empty list item

    def test_parse_story_with_invalid_id_format(self):
        data = "US001: As a user, I want to log in." # Intentionally missing hyphen
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [{"id": "US001", "text": "As a user, I want to log in."}])

    def test_parse_story_with_id_containing_spaces(self):
        data = "US - 001: As a user, I want to log in."
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [{"id": "US - 001", "text": "As a user, I want to log in."}])

    def test_parse_mixed_valid_and_invalid_stories(self):
        data = "US-001: As a user, I want to log in.\nInvalid Story\nUS-002: As a user, I want to log out."
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [
            {"id": "US-001", "text": "As a user, I want to log in."},
            {"id": "US-002", "text": "As a user, I want to log out."}
        ])

    def test_parse_story_with_only_id(self):
        data = "US-001:"
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [{"id": "US-001", "text": ""}])

    def test_parse_story_with_empty_description(self):
        data = "US-001:  "
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [{"id": "US-001", "text": ""}])

    def test_parse_multiple_lines_with_empty_lines(self):
         data = "US-001: As a user, I want to log in.\n\nUS-002: As a user, I want to log out.\n"
         result = self.parser.parse(StringIO(data))
         self.assertEqual(result, [
            {"id": "US-001", "text": "As a user, I want to log in."},
            {"id": "US-002", "text": "As a user, I want to log out."}
         ])

    def test_parse_story_ids_with_different_prefixes(self):
        data = "FEATURE-123: Do feature X\nBUG-456: Fix bug Y"
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [
            {"id": "FEATURE-123", "text": "Do feature X"},
            {"id": "BUG-456", "text": "Fix bug Y"}
        ])

    def test_parse_story_ids_with_leading_zeroes(self):
        data = "US-0001: Do feature X\nUS-0010: Fix bug Y"
        result = self.parser.parse(StringIO(data))
        self.assertEqual(result, [
            {"id": "US-0001", "text": "Do feature X"},
            {"id": "US-0010", "text": "Fix bug Y"}
        ])

if __name__ == '__main__':
    unittest.main()