import os
import subprocess

import matplotlib.pyplot as plt


def run_test(n, threads, threshold):
    cmd = f"./lab2 {n} {threads} {threshold}"
    process = subprocess.Popen(
        cmd.split(), stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, text=True
    )
    _, err = process.communicate()
    for line in err.split("\n"):
        if "STAT:" in line:
            try:
                # 1. Берем часть после "time=" -> "0.010061 sec"
                # 2. .split() разбивает по пробелу на ["0.010061", "sec"]
                # 3. [0] берет первый элемент -> "0.010061"
                time_value = line.split("time=")[1].split()[0]
                return float(time_value)
            except (IndexError, ValueError):
                continue
    return 0.0


def build_benchmark():
    data_sizes = {
        "Small (10^5)": 100000,
        "Medium (2*10^6)": 2000000,
        "Large (5*10^6)": 5000000,
    }

    threshold = 10000
    thread_counts = [1, 2, 4, 8, 12, 16]

    plt.figure(figsize=(14, 6))
    ax1 = plt.subplot(1, 2, 1)
    ax2 = plt.subplot(1, 2, 2)

    for label, n_size in data_sizes.items():
        times = []
        print(f"\nТестирование: {label}...")
        for t in thread_counts:
            t_exec = run_test(n_size, t, threshold)
            times.append(t_exec)
            print(f"  Потоков: {t} | Время: {t_exec:.4f}с")

        ax1.plot(thread_counts, times, "o-", label=label)
        t_seq = times[0]
        speedup = [t_seq / x if x > 0 else 1 for x in times]
        ax2.plot(thread_counts, speedup, "s-", label=label)

    ax1.set_xlabel("Потоки")
    ax1.set_ylabel("Время (сек)")
    ax1.set_title("Время выполнения")
    ax1.legend()
    ax1.grid(True)

    ax2.plot(
        thread_counts, thread_counts, "--", color="black", alpha=0.3, label="Идеал"
    )
    ax2.set_xlabel("Потоки")
    ax2.set_ylabel("Ускорение")
    ax2.set_title("Масштабируемость")
    ax2.legend()
    ax2.grid(True)

    plt.tight_layout()
    os.makedirs("out", exist_ok=True)
    plt.savefig("out/performance_results.png")
    print("\nГрафик производительности сохранен в out/performance_results.png")


if __name__ == "__main__":
    build_benchmark()
