from .terminal import печатать
print(" ")

def содержит(что, где, игнорировать_регистр=False):
    # функция проверяет, что хотя бы один элемент из "что" (или вся переменная целиком) содержится хотя бы в одном элементе из "где" (или является частью самой переменной "где")

    # функция возвращает True или False
    # переменные "что" и "где" могут быть двух видов:
        # 1. итерируемые объекты (кортеж или список), всеми элементами которых являются строки (текст)
        # 2. сама переменная может быть строкой (текстом)
    # при нарушении любого из этих пунктов будет вызвана ошибка с описанием проблемы
    # переменная "игнорировать_регистр" может принимать только True, или быть по умолчанию False. При передаче другого типа данных будет вызвана ошибка.
    # при получении в "что" или "где" пустых строк или пустых списков будет возвращаться False
    if type(что) not in [str, list, tuple]:
        ошибка = f"переменная \"что\" может быть только текстом, списком или кортежом. {type(что)}"
        raise TypeError(печатать(ошибка, красный=True, не_печатать=True))

    if type(где) not in [str, list, tuple]:
        ошибка = f"переменная \"где\" может быть только текстом, списком или кортежом. {type(где)}"
        raise TypeError(печатать(ошибка, красный=True, не_печатать=True))
    
    if type(игнорировать_регистр) != bool:
        ошибка = f"переменная \"где\" может быть только True или False. {type(игнорировать_регистр)}"
        raise TypeError(печатать(ошибка, красный=True, не_печатать=True))
    
    if type(что) != str:
        for элемент in что:
            if type(элемент) != str:
                ошибка = f"В переменной \"что\" оказался нетекстовый тип - {элемент}"
                raise TypeError(печатать(ошибка, красный=True, не_печатать=True))
    
    if type(где) != str:
        for элемент in где:
            if type(элемент) != str:
                ошибка = f"В переменной \"где\" оказался нетекстовый тип - {элемент}"
                raise TypeError(печатать(ошибка, красный=True, не_печатать=True))

    if игнорировать_регистр:
        if type(что) == str:
            что = что.lower()
        
        else:
            новый_список = []
            for элемент in что:
                новый_список.append(элемент.lower())
            что = новый_список


        if type(где) == str:
            где = где.lower()
        
        else:
            новый_список = []
            for элемент in где:
                новый_список.append(элемент.lower())
            где = новый_список
    
    if type(что) == type(где) == str:
        if что in где:
            return True
        
    if type(что) == str and type(где) != str:
        for элемент in где:
            if что in элемент:
                return True
    
    if type(что) != str and type(где) == str:
        for элемент in что:
            if элемент in где:
                return True
    
    if type(что) != str and type(где) != str:
        for элемент_что in что:
            for элемент_где in где:
                if элемент_что in элемент_где:
                    return True






    return False

def тесты():
    # TDD - Test Driven Development
    # Разработка функций после написания тестов к ней

    # Согласно этому принципу, нужно сначала написать тесты, которые проверят аспект работы каждой функции. Каждый рвз при разработке функции необходимо запускать тесты - если они все пройдены, значит функция точно работает правильно

    # При разработке тестов недопустимо использоване вычесдяемых переменных - тестируемая функция должна принять заранее подготовленные данные, а тест проверяет, согласуется ли её ответ с ожидаемым.
    # Например при тестировании функции "сумма" ей в аргументы передаются числа 15 и 10, исравнивается её ответ с числом 25, а не с вычислением 15 + 10.
    
    пройдено = []
    не_пройдено = []

    def тест(что, где, игнорировать_регистр, ожидаемый_ответ, название_теста):
        try:
            ответ = содержит(что, где, игнорировать_регистр)
            ошибка = None
        except Exception as error:
            ошибка = error
            ответ = "ошибка"

        if ответ == ожидаемый_ответ:
            пройдено.append(1)
            печатать(название_теста, зеленый=True)
        else:
            печатать(название_теста, красный=True)
            print(f"ожидаемый - {ожидаемый_ответ}")
            print(f"ответ     - {ответ}")
            if ошибка:
                print(ошибка)
            print()
            не_пройдено.append(0)
    
    тест(123, "где", True, "ошибка", "неправильный тип - что")
    тест("что", 123, True, "ошибка", "неправильный тип - где")
    тест("что", "где", "текст", "ошибка", "неправильный тип - игнорировать регистр")
    тест(["текст", "не цифра", 42], "где", False, "ошибка", "тип \"что\" типа str")
    тест(
        что="что",
        где=["текст", "не цифра", 42],
        игнорировать_регистр=False,
        ожидаемый_ответ="ошибка",
        название_теста='Переменной \"где\" типа не str'
        )
    
    варианты = [
        ["сырники", "кто-то ест Сырники", True, True, "что - строка; где - строка; игн_регистр - True; ответ - True"],
        ["сырники", "кто-то ест грибы", True, False, "что - строка; где - строка; игн_регистр - True; ответ - False"],
        ["Сырники", "кто-то ест Сырники", False, True, "что - строка; где - строка; игн_регистр - False; ответ - True"],
        ["сырники", "кто-то ест Сырники", False, False, "что - строка; где - строка; игн_регистр - False; ответ - False"],
        ["Сырники", ["кто-то ест Сырники", "кто-то ест грибы"], False, True, "что - строка; где - список; игн_регистр - False; ответ - True"],
        ["сырники", ["кто-то ест Сырники", "кто-то ест грибы"], False, False, "что - строка; где - список; игн_регистр - False; ответ - False"],
        ["сырники", ["кто-то ест Сырники", "кто-то ест грибы"], True, True, "что - строка; где - список; игн_регистр - True; ответ - True"],
        ["пряники", ["кто-то ест Сырники", "кто-то ест грибы"], True, False, "что - строка; где - список; игн_регистр - True; ответ - False"],
        [["Грибы", "Сырники"], "Кто-то ест Грибы", False, True, "что - список; где - строка; игн_регистр - False; ответ - True"],
        [["Грибы", "Сырники"], "Кто-то ест грибы", False, False, "что - список; где - строка; игн_регистр - False; ответ - False"],
        [["Грибы", "Сырники"], "Кто-то ест грибы", True, True, "что - список; где - строка; игн_регистр - True; ответ - True"],
        [["Грибы", "Сырники"], "Кто-то ест пряники", True, False, "что - список; где - строка; игн_регистр - True; ответ - False"],
        [["Грибы", "Сырники"], ["кто-то ест Сырники", "кто-то ест Грибы"], False, True, "что - список; где - список; игн_регистр - False; ответ - True"],
        [["Грибы", "Сырники"], ["кто-то ест сырники", "кто-то ест грибы"], False, False, "что - список; где - список; игн_регистр - False; ответ - False"],
        [["Грибы", "Сырники"], ["кто-то ест сырники", "кто-то ест грибы"], True, True, "что - список; где - список; игн_регистр - True; ответ - True"],
        [["Грибы", "Сырники"], ["кто-то ест пряники", "кто-то ест пельмени"], True, False, "что - список; где - список; игн_регистр - True; ответ - False"],
    ]

    for вариант in варианты:
        что, где, игнорировать_регистр, ответ, название = вариант
        тест(что, где, игнорировать_регистр, ответ, название)
    
    print(f"---------------------------------\nВсего тестов - {len(пройдено + не_пройдено)}\nПройдено - {len(пройдено)}\nНе пройдено - {len(не_пройдено)}")

тесты()