import time
import csv
import random

from phonebook import (ll_insert, ll_find, ll_delete, create_buckets, ht_insert, ht_find, ht_delete, bst_insert, bst_find, bst_delete)
from generator import generate_data

def run_exp():
    records_shuffled, records_sorted = generate_data(10000)
    all_names = [name for name, _ in records_shuffled]
    search_names = random.sample(all_names, 100) + [f"None_{i}" for i in range(10)]
    delete_names = random.sample(all_names, 50)

    results = [["Structura", "shuffled/sorted", "Operation", "Time"]]

    times =[]
    print('LinkedList - shuffled')
    for r in range(5):
        head = None
        start = time.perf_counter()
        for name, phone in records_shuffled:
            head = ll_insert(head, name, phone)
        times.append(time.perf_counter() - start)
    avg = sum(times)/5
    results.append(["LinkedList", "shuffled", "insert", avg])
    print(f"вставка - {avg:.6f}")

    times=[]
    for r in range(5):
        start = time.perf_counter()
        for name in search_names:
            ll_find(head, name)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["LinkedList", "shuffled", "find", avg])
    print(f"поиск - {avg:.6f}")

    times=[]
    for r in range(5):
        start = time.perf_counter()
        for name in delete_names:
            head = ll_delete(head, name)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["LinkedList", "shuffled", "delete", avg])
    print(f"удаление - {avg:.6f}")

    print('LinkedList - sorted')
    for r in range(5):
        head = None
        start = time.perf_counter()
        for name, phone in records_sorted:
            head = ll_insert(head, name, phone)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["LinkedList", "sorted", "insert", avg])
    print(f"вставка - {avg:.6f}")

    times = []
    for r in range(5):
        start = time.perf_counter()
        for name in search_names:
            ll_find(head, name)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["LinkedList", "sorted", "find", avg])
    print(f"поиск - {avg:.6f}")

    times = []
    for r in range(5):
        start = time.perf_counter()
        for name in delete_names:
            head = ll_delete(head, name)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["LinkedList", "sorted", "delete", avg])
    print(f"удаление - {avg:.6f}")

    print('HashTable - shuffled')
    times =[]
    for r in range(5):
        buckets = create_buckets(1000)
        start = time.perf_counter()
        for name, phone in records_shuffled:
            ht_insert(buckets,name,phone)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["HashTable", "shuffled", "insert", avg])
    print(f"вставка - {avg:.6f}")

    times = []
    for r in range(5):
        start = time.perf_counter()
        for name in search_names:
            ht_find(buckets, name)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["HashTable", "shuffled", "find", avg])
    print(f"поиск - {avg:.6f}")

    times = []
    for r in range(5):
        start = time.perf_counter()
        for name in delete_names:
            ht_delete(buckets, name)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["HashTable", "shuffled", "delete", avg])
    print(f"удаление - {avg:.6f}")

    print('sorted')
    times = []
    for r in range(5):
        buckets = create_buckets(1000)
        start = time.perf_counter()
        for name, phone in records_sorted:
            ht_insert(buckets, name, phone)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["HashTable", "sorted", "insert", avg])
    print(f"вставка - {avg:.6f}")

    times = []
    for r in range(5):
        start = time.perf_counter()
        for name in search_names:
            ht_find(buckets, name)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["HashTable", "sorted", "find", avg])
    print(f"поиск - {avg:.6f}")

    times = []
    for r in range(5):
        start = time.perf_counter()
        for name in delete_names:
            ht_delete(buckets, name)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["HashTable", "sorted", "delete", avg])
    print(f"удаление - {avg:.6f}")

    print("BST - shuffled")
    times = []
    for r in range(5):
        root = None
        start = time.perf_counter()
        for name, phone in records_shuffled:
            root = bst_insert(root, name, phone)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["Bst", "shuffled", "insert", avg])
    print(f"вставка - {avg:.6f}")

    times = []
    for r in range(5):
        start = time.perf_counter()
        for name in search_names:
            bst_find(root, name)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["Bst", "shuffled", "find", avg])
    print(f"поиск - {avg:.6f}")

    times = []
    for r in range(5):
        start = time.perf_counter()
        for name in delete_names:
            root = bst_delete(root, name)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["Bst", "shuffled", "delete", avg])
    print(f"удаление - {avg:.6f}")

    print('sorted')
    times = []
    for r in range(5):
        root = None
        start = time.perf_counter()
        for name, phone in records_sorted:
            root = bst_insert(root, name, phone)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["Bst", "sorted", "insert", avg])
    print(f"вставка - {avg:.6f}")

    times = []
    for r in range(5):
        start = time.perf_counter()
        for name in search_names:
            bst_find(root, name)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["Bst", "sorted", "find", avg])
    print(f"поиск - {avg:.6f}")

    times = []
    for r in range(5):
        start = time.perf_counter()
        for name in delete_names:
            root = bst_delete(root, name)
        times.append(time.perf_counter() - start)
    avg = sum(times) / 5
    results.append(["Bst", "sorted", "delete", avg])
    print(f"удаление - {avg:.6f}")

    with open("C:/Users/Honor/Documents/dep2k/lab_inf_1/data/results.csv", "w", newline="", encoding="utf-8") as f:
        writer = csv.writer(f)
        writer.writerows(results)
if __name__ == "__main__":
    run_exp()