"""Unit tests for NFO ID parsing functionality."""

import tempfile
from pathlib import Path

import pytest

from src.core.services.nfo_service import NFOService


class TestNFOIDParsing:
    """Test NFO ID parsing from XML files."""

    @pytest.fixture
    def nfo_service(self):
        """Create NFO service for testing."""
        with tempfile.TemporaryDirectory() as tmpdir:
            service = NFOService(
                tmdb_api_key="test_key",
                anime_directory=tmpdir,
                auto_create=False
            )
            yield service

    @pytest.fixture
    def temp_nfo_file(self):
        """Create a temporary NFO file for testing."""
        with tempfile.NamedTemporaryFile(
            mode='w', 
            suffix='.nfo', 
            delete=False,
            encoding='utf-8'
        ) as f:
            nfo_path = Path(f.name)
            yield nfo_path
            # Cleanup
            if nfo_path.exists():
                nfo_path.unlink()

    def test_parse_nfo_ids_with_uniqueid_elements(
        self, nfo_service, temp_nfo_file
    ):
        """Test parsing IDs from uniqueid elements."""
        nfo_content = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tvshow>
    <title>Attack on Titan</title>
    <uniqueid type="tmdb" default="true">1429</uniqueid>
    <uniqueid type="tvdb">295739</uniqueid>
    <uniqueid type="imdb">tt2560140</uniqueid>
</tvshow>"""
        temp_nfo_file.write_text(nfo_content, encoding='utf-8')
        
        result = nfo_service.parse_nfo_ids(temp_nfo_file)
        
        assert result["tmdb_id"] == 1429
        assert result["tvdb_id"] == 295739

    def test_parse_nfo_ids_with_dedicated_elements(
        self, nfo_service, temp_nfo_file
    ):
        """Test parsing IDs from dedicated tmdbid/tvdbid elements."""
        nfo_content = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tvshow>
    <title>One Piece</title>
    <tmdbid>37854</tmdbid>
    <tvdbid>81797</tvdbid>
</tvshow>"""
        temp_nfo_file.write_text(nfo_content, encoding='utf-8')
        
        result = nfo_service.parse_nfo_ids(temp_nfo_file)
        
        assert result["tmdb_id"] == 37854
        assert result["tvdb_id"] == 81797

    def test_parse_nfo_ids_mixed_formats(
        self, nfo_service, temp_nfo_file
    ):
        """Test parsing with both uniqueid and dedicated elements.
        
        uniqueid elements should take precedence.
        """
        nfo_content = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tvshow>
    <title>Naruto</title>
    <uniqueid type="tmdb" default="true">31910</uniqueid>
    <tmdbid>99999</tmdbid>
    <tvdbid>78857</tvdbid>
</tvshow>"""
        temp_nfo_file.write_text(nfo_content, encoding='utf-8')
        
        result = nfo_service.parse_nfo_ids(temp_nfo_file)
        
        # uniqueid should take precedence over tmdbid element
        assert result["tmdb_id"] == 31910
        assert result["tvdb_id"] == 78857

    def test_parse_nfo_ids_only_tmdb(
        self, nfo_service, temp_nfo_file
    ):
        """Test parsing when only TMDB ID is present."""
        nfo_content = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tvshow>
    <title>Dragon Ball Z</title>
    <uniqueid type="tmdb" default="true">1553</uniqueid>
</tvshow>"""
        temp_nfo_file.write_text(nfo_content, encoding='utf-8')
        
        result = nfo_service.parse_nfo_ids(temp_nfo_file)
        
        assert result["tmdb_id"] == 1553
        assert result["tvdb_id"] is None

    def test_parse_nfo_ids_only_tvdb(
        self, nfo_service, temp_nfo_file
    ):
        """Test parsing when only TVDB ID is present."""
        nfo_content = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tvshow>
    <title>Bleach</title>
    <uniqueid type="tvdb" default="true">74796</uniqueid>
</tvshow>"""
        temp_nfo_file.write_text(nfo_content, encoding='utf-8')
        
        result = nfo_service.parse_nfo_ids(temp_nfo_file)
        
        assert result["tmdb_id"] is None
        assert result["tvdb_id"] == 74796

    def test_parse_nfo_ids_no_ids(
        self, nfo_service, temp_nfo_file
    ):
        """Test parsing when no IDs are present."""
        nfo_content = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tvshow>
    <title>Unknown Series</title>
    <plot>A series without any IDs.</plot>
</tvshow>"""
        temp_nfo_file.write_text(nfo_content, encoding='utf-8')
        
        result = nfo_service.parse_nfo_ids(temp_nfo_file)
        
        assert result["tmdb_id"] is None
        assert result["tvdb_id"] is None

    def test_parse_nfo_ids_invalid_id_format(
        self, nfo_service, temp_nfo_file
    ):
        """Test parsing with invalid ID formats (non-numeric)."""
        nfo_content = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tvshow>
    <title>Invalid IDs</title>
    <uniqueid type="tmdb" default="true">not_a_number</uniqueid>
    <uniqueid type="tvdb">also_invalid</uniqueid>
</tvshow>"""
        temp_nfo_file.write_text(nfo_content, encoding='utf-8')
        
        result = nfo_service.parse_nfo_ids(temp_nfo_file)
        
        # Should return None for invalid formats instead of crashing
        assert result["tmdb_id"] is None
        assert result["tvdb_id"] is None

    def test_parse_nfo_ids_file_not_found(self, nfo_service):
        """Test parsing when NFO file doesn't exist."""
        non_existent = Path("/tmp/non_existent_nfo_file.nfo")
        
        result = nfo_service.parse_nfo_ids(non_existent)
        
        assert result["tmdb_id"] is None
        assert result["tvdb_id"] is None

    def test_parse_nfo_ids_invalid_xml(
        self, nfo_service, temp_nfo_file
    ):
        """Test parsing with invalid XML."""
        nfo_content = """<?xml version="1.0" encoding="UTF-8"?>
<tvshow>
    <title>Broken XML
    <!-- Missing closing tags -->
"""
        temp_nfo_file.write_text(nfo_content, encoding='utf-8')
        
        result = nfo_service.parse_nfo_ids(temp_nfo_file)
        
        # Should handle error gracefully and return None values
        assert result["tmdb_id"] is None
        assert result["tvdb_id"] is None

    def test_parse_nfo_ids_empty_file(
        self, nfo_service, temp_nfo_file
    ):
        """Test parsing an empty file."""
        temp_nfo_file.write_text("", encoding='utf-8')
        
        result = nfo_service.parse_nfo_ids(temp_nfo_file)
        
        assert result["tmdb_id"] is None
        assert result["tvdb_id"] is None
