# Запуск экспериментального сравнения трёх структур данных
# Результаты сохраняются в experiment_results.csv

import csv
import sys
sys.setrecursionlimit(20000)

import linked_list as ll
import hash_table as ht
import bst
import data_utils
import benchmark

def main():
    N = 10000                     # количество записей
    base_records = data_utils.generate_records(N)
    shuffled, sorted_records = data_utils.prepare_datasets(base_records)

    # Описания структур для бенчмарка
    structures = {
        'LinkedList': {
            'name': 'LinkedList',
            'create': lambda: None,
            'insert': ll.ll_insert,
            'find': ll.ll_find,
            'delete': ll.ll_delete
        },
        'HashTable': {
            'name': 'HashTable',
            'create': lambda: ht.create_hash_table(10),   # 10 корзин
            'insert': ht.ht_insert,
            'find': ht.ht_find,
            'delete': ht.ht_delete
        },
        'BST': {
            'name': 'BST',
            'create': lambda: None,
            'insert': bst.bst_insert,
            'find': bst.bst_find,
            'delete': bst.bst_delete
        }
    }

    all_results = []
    REPEATS = 5   # минимум 5 повторений

    for name, struct in structures.items():
        print(f"Testing {name} on random order...")
        res_random = benchmark.measure_operations(struct, shuffled, 'random', REPEATS)
        all_results.extend(res_random)

        print(f"Testing {name} on sorted order...")
        res_sorted = benchmark.measure_operations(struct, sorted_records, 'sorted', REPEATS)
        all_results.extend(res_sorted)

    # Сохранение CSV
    with open('experiment_results.csv', 'w', newline='', encoding='utf-8') as f:
        writer = csv.writer(f)
        writer.writerow(['Structure', 'Mode', 'Repeat', 'Insert (sec)', 'Search (sec)', 'Delete (sec)'])
        for row in all_results:
            writer.writerow([
                row['structure'],
                row['mode'],
                row['repetition'],
                f"{row['insert_time']:.6f}",
                f"{row['find_time']:.6f}",
                f"{row['delete_time']:.6f}"
            ])

    print("Experiment finished. Results saved to experiment_results.csv")

if __name__ == '__main__':
    main()