from typing import Any, Text, Dict, List

import pytest

from rasa.nlu.training_data import TrainingData
from rasa.nlu.constants import ENTITIES
from rasa.nlu.training_data import Message
from rasa.nlu.extractors.regex_entity_extractor import RegexEntityExtractor


@pytest.mark.parametrize(
    "text, lookup, expected_entities",
    [
        (
            "Berlin and London are cities.",
            [
                {
                    "name": "city",
                    "elements": ["Berlin", "Amsterdam", "New York", "London"],
                }
            ],
            [
                {
                    "entity": "city",
                    "value": "Berlin",
                    "start": 0,
                    "end": 6,
                    "extractor": "LookupEntityExtractor",
                },
                {
                    "entity": "city",
                    "value": "London",
                    "start": 11,
                    "end": 17,
                    "extractor": "LookupEntityExtractor",
                },
            ],
        ),
        (
            "Sophie is visiting Thomas in Berlin.",
            [
                {
                    "name": "city",
                    "elements": ["Berlin", "Amsterdam", "New York", "London"],
                },
                {"name": "person", "elements": ["Max", "John", "Sophie", "Lisa"]},
            ],
            [
                {
                    "entity": "city",
                    "value": "Berlin",
                    "start": 29,
                    "end": 35,
                    "extractor": "LookupEntityExtractor",
                },
                {
                    "entity": "person",
                    "value": "Sophie",
                    "start": 0,
                    "end": 6,
                    "extractor": "LookupEntityExtractor",
                },
            ],
        ),
        (
            "Rasa is great.",
            [
                {
                    "name": "city",
                    "elements": ["Berlin", "Amsterdam", "New York", "London"],
                },
                {"name": "person", "elements": ["Max", "John", "Sophie", "Lisa"]},
            ],
            [],
        ),
    ],
)
def test_process(
    text: Text,
    lookup: List[Dict[Text, List[Text]]],
    expected_entities: List[Dict[Text, Any]],
):
    message = Message(text)

    training_data = TrainingData()
    training_data.lookup_tables = lookup

    entity_extractor = RegexEntityExtractor()
    entity_extractor.train(training_data)
    entity_extractor.process(message)

    entities = message.get(ENTITIES)
    assert entities == expected_entities


@pytest.mark.parametrize(
    "text, lowercase, lookup, expected_entities",
    [
        (
            "berlin and London are cities.",
            False,
            [
                {
                    "name": "city",
                    "elements": ["Berlin", "Amsterdam", "New York", "London"],
                }
            ],
            [
                {
                    "entity": "city",
                    "value": "London",
                    "start": 11,
                    "end": 17,
                    "extractor": "LookupEntityExtractor",
                }
            ],
        ),
        (
            "berlin and London are cities.",
            True,
            [
                {
                    "name": "city",
                    "elements": ["Berlin", "Amsterdam", "New York", "london"],
                }
            ],
            [
                {
                    "entity": "city",
                    "value": "berlin",
                    "start": 0,
                    "end": 6,
                    "extractor": "LookupEntityExtractor",
                },
                {
                    "entity": "city",
                    "value": "London",
                    "start": 11,
                    "end": 17,
                    "extractor": "LookupEntityExtractor",
                },
            ],
        ),
    ],
)
def test_lowercase(
    text: Text,
    lowercase: bool,
    lookup: List[Dict[Text, List[Text]]],
    expected_entities: List[Dict[Text, Any]],
):
    message = Message(text)
    training_data = TrainingData()
    training_data.lookup_tables = lookup

    entity_extractor = RegexEntityExtractor({"lowercase": lowercase})
    entity_extractor.train(training_data)
    entity_extractor.process(message)

    entities = message.get(ENTITIES)
    assert entities == expected_entities


def test_do_not_overwrite_any_entities():
    message = Message("Max lives in Berlin.")
    message.set(ENTITIES, [{"entity": "person", "value": "Max", "start": 0, "end": 3}])

    training_data = TrainingData()
    training_data.lookup_tables = [
        {"name": "city", "elements": ["London", "Berlin", "Amsterdam"]}
    ]

    entity_extractor = RegexEntityExtractor()
    entity_extractor.train(training_data)
    entity_extractor.process(message)

    entities = message.get(ENTITIES)
    assert entities == [
        {"entity": "person", "value": "Max", "start": 0, "end": 3},
        {
            "entity": "city",
            "value": "Berlin",
            "start": 13,
            "end": 19,
            "extractor": "LookupEntityExtractor",
        },
    ]

@@ -762,38 +762,37 @@
   %22extractor%22: %22
-Lookup
+Regex
 EntityExtractor%22
@@ -997,38 +997,37 @@
   %22extractor%22: %22
-Lookup
+Regex
 EntityExtractor%22
@@ -1598,38 +1598,37 @@
   %22extractor%22: %22
-Lookup
+Regex
 EntityExtractor%22
@@ -1833,38 +1833,37 @@
   %22extractor%22: %22
-Lookup
+Regex
 EntityExtractor%22
@@ -3222,38 +3222,37 @@
   %22extractor%22: %22
-Lookup
+Regex
 EntityExtractor%22
@@ -3747,38 +3747,37 @@
   %22extractor%22: %22
-Lookup
+Regex
 EntityExtractor%22
@@ -3982,38 +3982,37 @@
   %22extractor%22: %22
-Lookup
+Regex
 EntityExtractor%22
@@ -5284,14 +5284,13 @@
 %22: %22
-Lookup
+Regex
 Enti

update component name in tests