#include <iostream>
#include <fstream>
#include <vector>
#include <thread>
#include <chrono>
#include <cstdlib>

// =====================
// Datei einlesen
// =====================
void readFile(const std::string& filename, std::vector<int>& data)
{
    std::ifstream file(filename);
    int value;
    while (file >> value)
        data.push_back(value);
}

// =====================
// Serielle Auswertung
// =====================
int countSerial(const std::vector<int>& messungen)
{
    if (messungen.size() < 2)
        return 0;

    int increases = 0;
    for (size_t i = 1; i < messungen.size(); ++i)
        if (messungen[i] > messungen[i - 1])
            ++increases;

    return increases;
}

// =====================
// Parallele Auswertung
// =====================
int countParallel(const std::vector<int>& messungen, int numThreads)
{
    if (messungen.size() < 2)
        return 0;

    int totalComparisons = messungen.size() - 1;
    if (numThreads > totalComparisons)
        numThreads = totalComparisons;

    std::vector<int> results(numThreads, 0);
    std::vector<std::thread> threads;

    int base = totalComparisons / numThreads;
    int remainder = totalComparisons % numThreads;

    int idx = 1;

    for (int t = 0; t < numThreads; ++t)
    {
        int startIdx = idx;
        int count = base + (t < remainder ? 1 : 0);
        int endIdx = idx + count - 1;
        idx = endIdx + 1;

        threads.emplace_back([&, t, startIdx, endIdx]()
        {
            int localCount = 0;
            for (int i = startIdx; i <= endIdx; ++i)
                if (messungen[i] > messungen[i - 1])
                    ++localCount;

            results[t] = localCount;
        });
    }

    for (auto& th : threads)
        th.join();

    int total = 0;
    for (int r : results)
        total += r;

    return total;
}

// =====================
// main
// =====================
int main()
{
    std::vector<int> messungen;

    // ===== Variante A: Datei =====
    readFile("measurements.txt", messungen);

    // ===== Variante B: künstliche Daten (statt Datei) =====
    /*
    int value = 0;
    for (size_t i = 0; i < 100000000; ++i)
        messungen.push_back(value += (rand() % 3 - 1));
    */

    // ===== Seriell =====
    auto start = std::chrono::steady_clock::now();
    int serialResult = countSerial(messungen);
    auto end = std::chrono::steady_clock::now();

    std::chrono::duration<double> serialTime = end - start;
    std::cout << "Seriell:  " << serialResult
              << " | Took: " << serialTime.count() << " s\n";

    // ===== Parallel =====
    int numThreads = std::thread::hardware_concurrency();
    if (numThreads == 0) numThreads = 4;

    start = std::chrono::steady_clock::now();
    int parallelResult = countParallel(messungen, numThreads);
    end = std::chrono::steady_clock::now();

    std::chrono::duration<double> parallelTime = end - start;
    std::cout << "Parallel: " << parallelResult
              << " | Took: " << parallelTime.count() << " s\n";

    return 0;
}
