@file:Suppress("HardCodedStringLiteral")

package eu.gaudian.translator.model.grammar

import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test

/**
 * Unit tests for AdjectiveVariationsParser.
 * 
 * These tests ensure that the parsing logic works correctly for different
 * languages and form combinations.
 */
class AdjectiveVariationsParserTest {

    @Test
    fun `isAdjectiveWithVariations returns true for French adjective with POS`() {
        val forms = listOf(
            FormData("beau", listOf("masculine", "singular"), emptyList()),
            FormData("belle", listOf("feminine", "singular"), emptyList())
        )
        
        val result = AdjectiveVariationsParser.isAdjectiveWithVariations(
            langCode = "fr",
            pos = "adjective",
            forms = forms
        )
        
        assertTrue("Should detect French adjective with POS", result)
    }

    @Test
    fun `isAdjectiveWithVariations returns true for French adjective without POS but with gender tags`() {
        val forms = listOf(
            FormData("beau", listOf("masculine", "singular"), emptyList()),
            FormData("belle", listOf("feminine", "singular"), emptyList())
        )
        
        val result = AdjectiveVariationsParser.isAdjectiveWithVariations(
            langCode = "fr",
            pos = null,
            forms = forms
        )
        
        assertTrue("Should detect French adjective by gender/number tags", result)
    }

    @Test
    fun `isAdjectiveWithVariations returns false for unsupported language`() {
        val forms = listOf(
            FormData("beautiful", listOf("masculine", "singular"), emptyList())
        )
        
        val result = AdjectiveVariationsParser.isAdjectiveWithVariations(
            langCode = "en",
            pos = "adjective",
            forms = forms
        )
        
        assertFalse("Should not detect adjective for unsupported language", result)
    }

    @Test
    fun `isAdjectiveWithVariations returns false for empty forms`() {
        val result = AdjectiveVariationsParser.isAdjectiveWithVariations(
            langCode = "fr",
            pos = "adjective",
            forms = emptyList()
        )
        
        assertFalse("Should not detect adjective with no forms", result)
    }

    @Test
    fun `isAdjectiveWithVariations returns false for forms without gender tags`() {
        val forms = listOf(
            FormData("beautiful", listOf("positive"), emptyList())
        )
        
        val result = AdjectiveVariationsParser.isAdjectiveWithVariations(
            langCode = "fr",
            pos = null,
            forms = forms
        )
        
        assertFalse("Should not detect adjective without gender/number tags", result)
    }

    @Test
    fun `parseVariations handles complete French adjective`() {
        val forms = listOf(
            FormData("beaux", listOf("plural", "masculine"), listOf("bo")),
            FormData("belle", listOf("singular", "feminine"), listOf("bɛl")),
            FormData("belles", listOf("plural", "feminine"), listOf("bɛl"))
        )
        
        val result = AdjectiveVariationsParser.parseVariations(forms, "beau")
        
        assertEquals("Should have 4 variations", 4, result.variations.size)
        assertTrue("Should have complete data", result.hasCompleteData)
        
        // Check masculine singular (should use lemma)
        val mascSingular = result.variations.find { 
            it.gender == "masculine" && it.number == "singular" 
        }
        assertNotNull("Should have masculine singular", mascSingular)
        assertEquals("beau", mascSingular!!.form)
        
        // Check masculine plural
        val mascPlural = result.variations.find { 
            it.gender == "masculine" && it.number == "plural" 
        }
        assertNotNull("Should have masculine plural", mascPlural)
        assertEquals("beaux", mascPlural!!.form)
        
        // Check feminine singular
        val femSingular = result.variations.find { 
            it.gender == "feminine" && it.number == "singular" 
        }
        assertNotNull("Should have feminine singular", femSingular)
        assertEquals("belle", femSingular!!.form)
        assertEquals(listOf("bɛl"), femSingular.ipas)
        
        // Check feminine plural
        val femPlural = result.variations.find { 
            it.gender == "feminine" && it.number == "plural" 
        }
        assertNotNull("Should have feminine plural", femPlural)
        assertEquals("belles", femPlural!!.form)
    }

    @Test
    fun `parseVariations handles incomplete data`() {
        val forms = listOf(
            FormData("belle", listOf("singular", "feminine"), emptyList()),
            FormData("belles", listOf("plural", "feminine"), emptyList())
        )
        
        val result = AdjectiveVariationsParser.parseVariations(forms, "beau")
        
        assertEquals("Should have 3 variations (2 from forms + 1 from lemma)", 3, result.variations.size)
        assertFalse("Should not have complete data", result.hasCompleteData)
        
        // Should have masculine singular from lemma
        val mascSingular = result.variations.find { 
            it.gender == "masculine" && it.number == "singular" 
        }
        assertNotNull("Should have masculine singular from lemma", mascSingular)
        assertEquals("beau", mascSingular!!.form)
    }

    @Test
    fun `parseVariations handles no lemma fallback`() {
        val forms = listOf(
            FormData("belle", listOf("singular", "feminine"), emptyList()),
            FormData("belles", listOf("plural", "feminine"), emptyList())
        )
        
        val result = AdjectiveVariationsParser.parseVariations(forms, null)
        
        assertEquals("Should have 2 variations", 2, result.variations.size)
        assertFalse("Should not have complete data", result.hasCompleteData)
        
        // Should not have masculine singular without lemma
        val mascSingular = result.variations.find { 
            it.gender == "masculine" && it.number == "singular" 
        }
        assertNull("Should not have masculine singular without lemma", mascSingular)
    }

    @Test
    fun `getLanguageDisplayLabels returns French labels`() {
        val labels = AdjectiveVariationsParser.getLanguageDisplayLabels("fr")
        
        assertEquals("Masculin", labels["masculine"])
        assertEquals("Féminin", labels["feminine"])
        assertEquals("Singulier", labels["singular"])
        assertEquals("Pluriel", labels["plural"])
    }

    @Test
    fun `getLanguageDisplayLabels returns Portuguese labels`() {
        val labels = AdjectiveVariationsParser.getLanguageDisplayLabels("pt")
        
        assertEquals("Masculino", labels["masculine"])
        assertEquals("Feminino", labels["feminine"])
        assertEquals("Singular", labels["singular"])
        assertEquals("Plural", labels["plural"])
    }

    @Test
    fun `getLanguageDisplayLabels returns German labels`() {
        val labels = AdjectiveVariationsParser.getLanguageDisplayLabels("de")
        
        assertEquals("Maskulin", labels["masculine"])
        assertEquals("Feminin", labels["feminine"])
        assertEquals("Neutrum", labels["neuter"])
        assertEquals("Singular", labels["singular"])
        assertEquals("Plural", labels["plural"])
    }

    @Test
    fun `getLanguageDisplayLabels returns English labels for unsupported language`() {
        val labels = AdjectiveVariationsParser.getLanguageDisplayLabels("es")
        
        assertEquals("Masculine", labels["masculine"])
        assertEquals("Feminine", labels["feminine"])
        assertEquals("Neuter", labels["neuter"])
        assertEquals("Singular", labels["singular"])
        assertEquals("Plural", labels["plural"])
    }

    @Test
    fun `parseVariations handles German adjective with neuter`() {
        val forms = listOf(
            FormData("gut", listOf("masculine", "singular"), emptyList()),
            FormData("gute", listOf("feminine", "singular"), emptyList()),
            FormData("gut", listOf("neuter", "singular"), emptyList()),
            FormData("gute", listOf("plural"), emptyList())
        )
        
        val result = AdjectiveVariationsParser.parseVariations(forms, "gut")
        
        assertEquals("Should have 4 variations", 4, result.variations.size)
        
        // Check neuter singular
        val neuterSingular = result.variations.find { 
            it.gender == "neuter" && it.number == "singular" 
        }
        assertNotNull("Should have neuter singular", neuterSingular)
        assertEquals("gut", neuterSingular!!.form)
    }

    @Test
    fun `parseVariations handles case insensitive tags`() {
        val forms = listOf(
            FormData("Belle", listOf("SINGULAR", "FEMININE"), emptyList())
        )
        
        val result = AdjectiveVariationsParser.parseVariations(forms, "beau")
        
        assertEquals("Should have 1 variation", 1, result.variations.size)
        
        val variation = result.variations.first()
        assertEquals("feminine", variation.gender)
        assertEquals("singular", variation.number)
        assertEquals("Belle", variation.form)
    }
}
