"""Tests for all 4 parsers."""

import pytest
from pathlib import Path

from ai_checkup.parsers import detect_and_parse
from ai_checkup.parsers.chatgpt import ChatGPTParser
from ai_checkup.parsers.claude import ClaudeParser
from ai_checkup.parsers.gemini import GeminiParser
from ai_checkup.parsers.csv_generic import CSVParser


class TestChatGPTParser:
    def test_can_parse(self, chatgpt_path):
        parser = ChatGPTParser()
        assert parser.can_parse(chatgpt_path)

    def test_cannot_parse_csv(self, csv_path):
        parser = ChatGPTParser()
        assert not parser.can_parse(csv_path)

    def test_parse_count(self, chatgpt_path):
        parser = ChatGPTParser()
        convs = parser.parse(chatgpt_path)
        assert len(convs) == 20

    def test_parse_content(self, chatgpt_path):
        parser = ChatGPTParser()
        convs = parser.parse(chatgpt_path)
        # First conversation should be about Python crawler
        first = convs[0]
        assert "Python" in first.first_prompt or "爬虫" in first.first_prompt
        assert first.platform == "chatgpt"
        assert first.created is not None

    def test_parse_messages(self, chatgpt_path):
        parser = ChatGPTParser()
        convs = parser.parse(chatgpt_path)
        # Each conversation should have user + assistant messages (system filtered out)
        for conv in convs:
            roles = [m.role for m in conv.messages]
            assert "user" in roles
            assert "assistant" in roles
            assert "system" not in roles


class TestClaudeParser:
    def test_can_parse(self, claude_path):
        parser = ClaudeParser()
        assert parser.can_parse(claude_path)

    def test_cannot_parse_csv(self, csv_path):
        parser = ClaudeParser()
        assert not parser.can_parse(csv_path)

    def test_parse_count(self, claude_path):
        parser = ClaudeParser()
        convs = parser.parse(claude_path)
        assert len(convs) == 20

    def test_parse_content(self, claude_path):
        parser = ClaudeParser()
        convs = parser.parse(claude_path)
        first = convs[0]
        assert first.first_prompt != ""
        assert first.platform == "claude"
        assert first.created is not None

    def test_parse_metadata(self, claude_path):
        parser = ClaudeParser()
        convs = parser.parse(claude_path)
        for conv in convs:
            assert "message_count" in conv.metadata


class TestGeminiParser:
    def test_can_parse(self, gemini_path):
        parser = GeminiParser()
        assert parser.can_parse(gemini_path)

    def test_cannot_parse_chatgpt(self, chatgpt_path):
        parser = GeminiParser()
        assert not parser.can_parse(chatgpt_path)

    def test_parse_count(self, gemini_path):
        parser = GeminiParser()
        convs = parser.parse(gemini_path)
        assert len(convs) == 20

    def test_parse_content(self, gemini_path):
        parser = GeminiParser()
        convs = parser.parse(gemini_path)
        first = convs[0]
        assert first.first_prompt != ""
        assert first.platform == "gemini"


class TestCSVParser:
    def test_can_parse(self, csv_path):
        parser = CSVParser()
        assert parser.can_parse(csv_path)

    def test_cannot_parse_json(self, chatgpt_path):
        parser = CSVParser()
        assert not parser.can_parse(chatgpt_path)

    def test_parse_count(self, csv_path):
        parser = CSVParser()
        convs = parser.parse(csv_path)
        assert len(convs) == 20

    def test_parse_content(self, csv_path):
        parser = CSVParser()
        convs = parser.parse(csv_path)
        first = convs[0]
        assert first.first_prompt != ""
        assert first.platform == "csv"


class TestAutoDetect:
    def test_detect_chatgpt(self, chatgpt_path):
        convs = detect_and_parse(chatgpt_path)
        assert len(convs) == 20
        assert convs[0].platform == "chatgpt"

    def test_detect_claude(self, claude_path):
        convs = detect_and_parse(claude_path)
        assert len(convs) == 20
        assert convs[0].platform == "claude"

    def test_detect_gemini(self, gemini_path):
        convs = detect_and_parse(gemini_path)
        assert len(convs) == 20
        assert convs[0].platform == "gemini"

    def test_detect_csv(self, csv_path):
        convs = detect_and_parse(csv_path)
        assert len(convs) == 20
        assert convs[0].platform == "csv"

    def test_invalid_path(self, tmp_path):
        with pytest.raises(FileNotFoundError):
            detect_and_parse(tmp_path / "nonexistent.json")

    def test_unknown_format(self, tmp_path):
        bad_file = tmp_path / "bad.json"
        bad_file.write_text('{"not": "conversation data"}')
        with pytest.raises(ValueError, match="Cannot detect format"):
            detect_and_parse(bad_file)
