import subprocess
import os

'''
Тесты для программы поиска простых чисел в одном потоке.
Есть 2 варианта тестов: В 1 проверяется корректность найденного количества простых чисел. 
В 2 проверяется больше n для проверки корректности выделения памяти, но нет точных 
значений кол-ва простых чисел для многих n.
Запускает программу с аргументами 1, n через команду ./filename 1 n
Значение n берется из списка n_values_1 или n_values_2
Результат выполнения записывается в results.txt 
Тесты подходят под определенный формат консольного вывода программы:
	Найдено X =текст=
	Время выполнения: T =текст=
	=текст=
	=ПОЛЬЗОВАТЕЛЬСКИЙ ВВОД 1 СТРОКИ=
'''

file_name = 'primes' # Имя программы, изменить если другое
test_variant = 2 # Вариант тестов 1 или 2. Изменить в зависимости от требований
file_run_command = './' + file_name 

if not os.path.isfile(file_run_command) or not os.access(file_run_command, os.X_OK):
    print("Ошибка: файл ", file_name, " не существует или не имеет прав на выполнение")
    print("Убедитесь, что файл существует в текущей директории и/или выполните:")
    print("chmod +x primes")
    exit(1)

# Списки значений n
n_values_1 = ( 
    list(range(2, 33)) +                # 2-33
    list(range(100, 1001, 50)) +        # 100-1000 с шагом 50
    list(range(1500, 10001, 500)) +     # 1500-10000 с шагом 500
    [10**5, 10**6, 10**7, 10**8, 10**9, 10**10]  # степени 10
)

n_values_2 = ( # проверяется больше n. требуют больше времени, файл результата будет больше
	       # нужен для проверки корректности выделения памяти
    list(range(2, 9999)) +                # 2-9999
    list(range(10000, 50001, 50)) +        # 10000-50000 с шагом 50
    [10**5, 10**6, 10**7, 10**8, 10**9, 10**10]  # степени 10
)

# Точные значения количества простых чисел для диапазонов [1, n] для n_values_1
# Для n_values_2 будет множетсво тестов с результатом "без проверки"
prime_counts = {
    2: 1, 3: 2, 4: 2, 5: 3, 6: 3, 7: 4, 8: 4, 9: 4, 10: 4,
    11: 5, 12: 5, 13: 6, 14: 6, 15: 6, 16: 6, 17: 7, 18: 7, 19: 8, 20: 8,
    21: 8, 22: 8, 23: 9, 24: 9, 25: 9, 26: 9, 27: 9, 28: 9, 29: 10, 30: 10,
    31: 11, 32: 11,
    100: 25,
    150: 35,
    200: 46,
    250: 53,
    300: 62,
    350: 70,
    400: 78,
    450: 87,
    500: 95,
    550: 101,  
    600: 109,
    650: 118,  
    700: 125,
    750: 132,
    800: 139,
    850: 146,
    900: 154,
    950: 161,  
    1000: 168,
    1500: 239,
    2000: 303,
    2500: 367,
    3000: 430,
    3500: 489,  
    4000: 550,
    4500: 610,
    5000: 669,
    5500: 725,
    6000: 783,
    6500: 842,  
    7000: 900,
    7500: 950,  
    8000: 1007,
    8500: 1059,  
    9000: 1117,
    9500: 1177,  
    10000: 1229,
    100000: 9592,
    1000000: 78498,
    10000000: 664579,
    100000000: 5761455,
    1000000000: 50847534,
    10000000000: 455052511
}

# Статистика
total_tests = 0
passed_tests = 0
failed_tests = 0
unchecked_tests = 0

# Запуск тестов
with open('results.txt', 'w') as output_file:
    variant = n_values_1
    if test_variant == 2 :
    	variant = n_values_2
    for n in variant:
        command = ['./primes', '1', str(n)]
        print(f"Запуск: {' '.join(command)}")
        total_tests += 1
        
        try:
            result = subprocess.run(
                command,
                input='n\n',  
                check=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                timeout=172800
            )

            output_lines = result.stdout.strip().split('\n')
            result_lines = []
            found_count = None
            
            for line in output_lines:
                if 'Найдено' in line:
                    result_lines.append(line)
                    try:
                        found_count = int(line.split()[1])
                    except (IndexError, ValueError):
                        pass
                elif 'Время выполнения:' in line:
                    result_lines.append(line)
                elif 'Вывести все простые числа?' in line:
                    break

            test_passed = True
            if found_count is not None and n in prime_counts:
                expected_count = prime_counts[n]
                if found_count != expected_count:
                    test_passed = False
                    error_line = f"Ошибка: для N={n} найдено {found_count} простых чисел, а должно быть {expected_count}"
                    result_lines.append(error_line)
                    print(f"  {error_line}")
                    failed_tests += 1
                else:
                    #result_lines.append(f"Успех: для N={n} найдено верное количество простых чисел: {found_count}")
                    passed_tests += 1
            else:
                if n not in prime_counts:
                    result_lines.append(f"Предупреждение: нет значения для N={n}")

            for line in result_lines:
                output_file.write(line + '\n')
            output_file.write('\n')
            
            if test_passed and n in prime_counts:
                print("  Тест пройден успешно")
            
        except subprocess.CalledProcessError as e:
            error_msg = f"Ошибка выполнения (код {e.returncode}) для N={n}:\n{e.stderr}\n"
            output_file.write(error_msg)
            print(error_msg)
            failed_tests += 1
        except subprocess.TimeoutExpired:
            error_msg = f"Таймаут выполнения для N={n}\n\n"
            output_file.write(error_msg)
            print(error_msg)
            failed_tests += 1

print("\n" + "="*50)
unchecked_tests = total_tests - passed_tests - failed_tests
print(f"ИТОГОВАЯ СТАТИСТИКА:")
print(f"Всего тестов: {total_tests}")
print(f"Успешно пройдено: {passed_tests}")
print(f"Провалено: {failed_tests}")
print(f"Без проверки: {unchecked_tests}")
print("="*50)

if failed_tests == 0 and unchecked_tests == 0:
    print("Все тесты пройдены успешно!")

print(f"\nРезультаты записаны в results.txt")

в консоли нет вывода, о том что нет точного значения для n. помогиисправить, пожалуйста