import pytest

from spacy.tokens import Doc


# fmt: off
@pytest.mark.parametrize(
    "words,heads,deps,pos,chunk_offsets",
    [
        # determiner + noun
        # un nom -> un nom
        (
            ["un", "nom"],
            [1, 1],
            ["det", "ROOT"],
            ["DET", "NOUN"],
            [(0, 2)],
        ),
        # determiner + noun starting with vowel
        # l'heure -> l'heure
        (
            ["l'", "heure"],
            [1, 1],
            ["det", "ROOT"],
            ["DET", "NOUN"],
            [(0, 2)],
        ),
        # determiner + plural noun
        # les romans -> les romans
        (
            ["les", "romans"],
            [1, 1],
            ["det", "ROOT"],
            ["DET", "NOUN"],
            [(0, 2)],
        ),
        # det + adj + noun
        # Le vieux Londres  -> Le vieux Londres
        (
            ['Les', 'vieux', 'Londres'],
            [2, 2, 2],
            ["det", "amod", "ROOT"],
            ["DET", "ADJ", "NOUN"],
            [(0,3)]
        ),
        # det + noun + adj
        # le nom propre  -> le nom propre   a proper noun
        (
            ["le", "nom", "propre"],
            [1, 1, 1],
            ["det", "ROOT", "amod"],
            ["DET", "NOUN", "ADJ"],
            [(0, 3)],
        ),
        # det + noun + adj plural
        # Les chiens bruns  -> les chiens bruns
        (
            ["Les", "chiens", "bruns"],
            [1, 1, 1],
            ["det", "ROOT", "amod"],
            ["DET", "NOUN", "ADJ"],
            [(0, 3)],
        ),
        # multiple adjectives: one adj before the noun, one adj after the noun
        # un nouveau film intéressant -> un nouveau film intéressant
        (
            ["un", "nouveau", "film", "intéressant"],
            [2, 2, 2, 2],
            ["det", "amod", "ROOT", "amod"],
            ["DET", "ADJ", "NOUN", "ADJ"],
            [(0,4)]
        ),
        # multiple adjectives, both adjs after the noun
        # une personne intelligente et drôle -> une personne intelligente et drôle
        (
            ["une", "personne", "intelligente", "et", "drôle"],
            [1, 1, 1, 4, 2],
            ["det", "ROOT", "amod", "cc", "conj"],
            ["DET", "NOUN", "ADJ", "CCONJ", "ADJ"],
            [(0,5)]
        ),
        # relative pronoun
        # un bus qui va au ville -> un bus, qui, ville
        (
            ['un', 'bus', 'qui', 'va', 'au', 'ville'],
            [1, 1, 3, 1, 5, 3],
            ['det', 'ROOT', 'nsubj', 'acl:relcl', 'case', 'obl:arg'],
            ['DET', 'NOUN', 'PRON', 'VERB', 'ADP', 'NOUN'],
            [(0,2), (2,3), (5,6)]
        ),
        # relative subclause
        # Voilà la maison que nous voulons acheter -> la maison, nous         That's the house that we want to buy.
        (
            ['Voilà', 'la', 'maison', 'que', 'nous', 'voulons', 'acheter'],
            [0, 2, 0, 5, 5, 2, 5],
            ['ROOT', 'det', 'obj', 'mark', 'nsubj', 'acl:relcl', 'xcomp'],
            ['VERB', 'DET', 'NOUN', 'SCONJ', 'PRON', 'VERB', 'VERB'],
            [(1,3), (4,5)]
        ),
        # Person name and title by flat
        # Louis XIV -> Louis XIV
        (
            ["Louis", "XIV"],
            [0, 0],
            ["ROOT", "flat:name"],
            ["PROPN", "PROPN"],
            [(0,2)]
        ),
        # Organization name by flat
        # Nations Unies -> Nations Unies
        (
            ["Nations", "Unies"],
            [0, 0],
            ["ROOT", "flat:name"],
            ["PROPN", "PROPN"],
            [(0,2)]
        ),
        # Noun compound, person name created by two flats
        # Louise de Bratagne -> Louise de Bratagne
        (
            ["Louise", "de", "Bratagne"],
            [0, 0, 0],
            ["ROOT", "flat:name", "flat:name"],
            ["PROPN", "PROPN", "PROPN"],
            [(0,3)]
        ),
        # Noun compound, person name created by two flats
        # Louis François Joseph -> Louis François Joseph
        (
            ["Louis", "François", "Joseph"],
            [0, 0, 0],
            ["ROOT", "flat:name", "flat:name"],
            ["PROPN", "PROPN", "PROPN"],
            [(0,3)]
        ),
        # one determiner + one noun + one adjective qualified by an adverb
        # quelques agriculteurs très riches -> quelques agriculteurs très riches
        (
            ["quelques", "agriculteurs", "très", "riches"],
            [1, 1, 3, 1],
            ['det', 'ROOT', 'advmod', 'amod'],
            ['DET', 'NOUN', 'ADV', 'ADJ'],
            [(0,4)]
        ),
        # Two NPs conjuncted
        # Il a un chien et un chat -> Il, un chien, un chat
        (
            ['Il', 'a', 'un', 'chien', 'et', 'un', 'chat'],
            [1, 1, 3, 1, 6, 6, 3],
            ['nsubj', 'ROOT', 'det', 'obj', 'cc', 'det', 'conj'],
            ['PRON', 'VERB', 'DET', 'NOUN', 'CCONJ', 'DET', 'NOUN'],
            [(0,1), (2,4), (5,7)]

        ),
        # Two NPs together
        # l'écrivain brésilien Aníbal Machado -> l'écrivain brésilien, Aníbal Machado
        (
            ["l'", 'écrivain', 'brésilien', 'Aníbal', 'Machado'],
            [1, 1, 1, 1, 3],
            ['det', 'ROOT', 'amod', 'appos', 'flat:name'],
            ['DET', 'NOUN', 'ADJ', 'PROPN', 'PROPN'],
            [(0, 3), (3, 5)]
        ),
        # nmod relation between NPs
        # la destruction de la ville -> la destruction, la ville
        (
            ['la', 'destruction', 'de', 'la', 'ville'],
            [1, 1, 4, 4, 1],
            ['det', 'ROOT', 'case', 'det', 'nmod'],
            ['DET', 'NOUN', 'ADP', 'DET', 'NOUN'],
            [(0,2), (3,5)]
        ),
        # nmod relation between NPs
        # Archiduchesse d’Autriche -> Archiduchesse, Autriche
        (
            ['Archiduchesse', 'd’', 'Autriche'],
            [0, 2, 0],
            ['ROOT', 'case', 'nmod'],
            ['NOUN', 'ADP', 'PROPN'],
            [(0,1), (2,3)]
        ),
        # Compounding by nmod, several NPs chained together
        # la première usine de drogue du gouvernement -> la première usine, drogue, gouvernement
        (
            ["la", "première", "usine", "de", "drogue", "du", "gouvernement"],
            [2, 2, 2, 4, 2, 6, 2],
            ['det', 'amod', 'ROOT', 'case', 'nmod', 'case', 'nmod'],
            ['DET', 'ADJ', 'NOUN', 'ADP', 'NOUN', 'ADP', 'NOUN'],
            [(0, 3), (4, 5), (6, 7)]
        ),
        # several NPs
        # Traduction du rapport de Susana -> Traduction, rapport, Susana
        (
            ['Traduction', 'du', 'raport', 'de', 'Susana'],
            [0, 2, 0, 4, 2],
            ['ROOT', 'case', 'nmod', 'case', 'nmod'],
            ['NOUN', 'ADP', 'NOUN', 'ADP', 'PROPN'],
            [(0,1), (2,3), (4,5)]

        ),
        # Several NPs
        # Le gros chat de Susana et son amie -> Le gros chat, Susana, son amie
        (
            ['Le', 'gros', 'chat', 'de', 'Susana', 'et', 'son', 'amie'],
            [2, 2, 2, 4, 2, 7, 7, 2],
            ['det', 'amod', 'ROOT', 'case', 'nmod', 'cc', 'det', 'conj'],
            ['DET', 'ADJ', 'NOUN', 'ADP', 'PROPN', 'CCONJ', 'DET', 'NOUN'],
            [(0,3), (4,5), (6,8)]
        ),
        # Passive subject
        # Les nouvelles dépenses sont alimentées par le grand compte bancaire de Clinton -> Les nouvelles dépenses, le grand compte bancaire, Clinton
        (
            ['Les', 'nouvelles', 'dépenses', 'sont', 'alimentées', 'par', 'le', 'grand', 'compte', 'bancaire', 'de', 'Clinton'],
            [2, 2, 4, 4, 4, 8, 8, 8, 4, 8, 11, 8],
            ['det', 'amod', 'nsubj:pass', 'aux:pass', 'ROOT', 'case', 'det', 'amod', 'obl:agent', 'amod', 'case', 'nmod'],
            ['DET', 'ADJ', 'NOUN', 'AUX', 'VERB', 'ADP', 'DET', 'ADJ', 'NOUN', 'ADJ', 'ADP', 'PROPN'],
            [(0, 3), (6, 10), (11, 12)]
        )
    ],
)
# fmt: on
def test_fr_noun_chunks(fr_vocab, words, heads, deps, pos, chunk_offsets):
    doc = Doc(fr_vocab, words=words, heads=heads, deps=deps, pos=pos)
    assert [(c.start, c.end) for c in doc.noun_chunks] == chunk_offsets


def test_noun_chunks_is_parsed_fr(fr_tokenizer):
    """Test that noun_chunks raises Value Error for 'fr' language if Doc is not parsed."""
    doc = fr_tokenizer("Je suis allé à l'école")
    with pytest.raises(ValueError):
        list(doc.noun_chunks)
