/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Benchmark.h"
#include "OverwriteLine.h"
#include "SkGraphics.h"
#include "SkTaskGroup.h"
#include <algorithm>
#include <chrono>
#include <limits>
#include <regex>
#include <stdlib.h>
#include <string>
#include <vector>


#if defined(SK_BUILD_FOR_WIN32)
static const char* kEllipsis = "...";
#else
static const char* kEllipsis = "…";
#endif

int main(int argc, char** argv) {
    SkGraphics::Init();
    SkTaskGroup::Enabler enabled;

    using clock = std::chrono::high_resolution_clock;
    using ns = std::chrono::duration<double, std::nano>;

    std::regex pattern;
    int limit = 2147483647;
    if (argc > 1) { pattern = argv[1]; }
    if (argc > 2) { limit = atoi(argv[2]); }

    struct Bench {
        std::unique_ptr<Benchmark> b;
        std::string                name;
        ns                         best;
    };
    std::vector<Bench> benches;

    for (auto r = BenchRegistry::Head(); r; r = r->next()) {
        std::unique_ptr<Benchmark> bench{ r->factory()(nullptr) };

        std::string name = bench->getName();
        if (std::regex_search(name, pattern) &&
                bench->isSuitableFor(Benchmark::kNonRendering_Backend)) {
            bench->delayedSetup();
            benches.emplace_back(Bench{std::move(bench), name,
                                       ns{std::numeric_limits<double>::infinity()}});
        }
    }

    if (benches.size() == 0) {
        SkDebugf("No bench matched.\n");
        return 1;
    }

    if (benches.size() > 1) {
        int common_prefix = benches[0].name.size();
        for (size_t i = 1; i < benches.size(); i++) {
            int len = std::mismatch(benches[i-1].name.begin(), benches[i-1].name.end(),
                                    benches[i-0].name.begin())
                .first - benches[i-1].name.begin();
            common_prefix = std::min(common_prefix, len);
        }
        std::string prefix = benches[0].name.substr(0, common_prefix);
        if (common_prefix) {
            for (auto& bench : benches) {
                bench.name.replace(0, common_prefix, kEllipsis);
            }
        }

        int common_suffix = benches[0].name.size();
        for (size_t i = 1; i < benches.size(); i++) {
            int len = std::mismatch(benches[i-1].name.rbegin(), benches[i-1].name.rend(),
                                    benches[i-0].name.rbegin())
                .first - benches[i-1].name.rbegin();
            common_suffix = std::min(common_suffix, len);
        }
        std::string suffix = benches[0].name.substr(benches[0].name.size() - common_suffix);
        if (common_suffix) {
            for (auto& bench : benches) {
                bench.name.replace(bench.name.size() - common_suffix, common_suffix, kEllipsis);
            }
        }

        SkDebugf("%s%s%s\n", prefix.c_str(), kEllipsis, suffix.c_str());
    }

    int samples = 0;
    while (samples < limit) {
        for (auto& bench : benches) {
            for (int loops = 1; loops < 1000000000;) {
                bench.b->preDraw(nullptr);
                auto start = clock::now();
                    bench.b->draw(loops, nullptr);
                ns elapsed = clock::now() - start;
                bench.b->postDraw(nullptr);

                if (elapsed < std::chrono::milliseconds{10}) {
                    loops *= 2;
                    continue;
                }

                bench.best = std::min(bench.best, elapsed / loops);
                samples++;

                std::sort(benches.begin(), benches.end(), [](const Bench& a, const Bench& b) {
                    return a.best < b.best;
                });
                SkDebugf("%s%d", kSkOverwriteLine, samples);
                for (auto& bench : benches) {
                    if (benches.size() == 1) {
                        SkDebugf("  %s %gns" , bench.name.c_str(), bench.best.count());
                    } else {
                        SkDebugf("  %s %.3gx", bench.name.c_str(), bench.best / benches[0].best);
                    }
                }
                break;
            }
        }
    }

    return 0;
}
