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

#include <VisualBench/VisualBenchmarkStream.h>
#include <VisualBench/WrappedBenchmark.h>
#include "GMBench.h"
#include "SkOSFile.h"
#include "SkPath.h"
#include "SkPictureRecorder.h"
#include "SkStream.h"
#include "sk_tool_utils.h"
#include "VisualFlags.h"
#include "VisualSKPBench.h"

DEFINE_bool(cpu, false, "Run in CPU mode?");
DEFINE_string2(match, m, nullptr,
               "[~][^]substring[$] [...] of bench name to run.\n"
               "Multiple matches may be separated by spaces.\n"
               "~ causes a matching bench to always be skipped\n"
               "^ requires the start of the bench to match\n"
               "$ requires the end of the bench to match\n"
               "^ and $ requires an exact match\n"
               "If a bench does not match any list entry,\n"
               "it is skipped unless some list entry starts with ~");
DEFINE_string(skps, "skps", "Directory to read skps from.");

// We draw a big nonAA path to warmup the gpu / cpu
#include "SkPerlinNoiseShader.h"
class WarmupBench : public Benchmark {
public:
    WarmupBench() {
        sk_tool_utils::make_big_path(fPath);
    }
private:
    const char* onGetName() override { return "warmupbench"; }
    void onDraw(int loops, SkCanvas* canvas) override {
        // We draw a big path to warm up the cpu, and then use perlin noise shader to warm up the
        // gpu
        SkPaint paint;
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeWidth(2);

        SkPaint perlinPaint;
        perlinPaint.setShader(SkPerlinNoiseShader::CreateTurbulence(0.1f, 0.1f, 1, 0,
                                                                    nullptr))->unref();
        SkRect rect = SkRect::MakeLTRB(0., 0., 400., 400.);
        for (int i = 0; i < loops; i++) {
            canvas->drawPath(fPath, paint);
            canvas->drawRect(rect, perlinPaint);
        }
    }
    SkPath fPath;
};

VisualBenchmarkStream::VisualBenchmarkStream()
    : fBenches(BenchRegistry::Head())
    , fGMs(skiagm::GMRegistry::Head())
    , fSourceType(nullptr)
    , fBenchType(nullptr)
    , fCurrentSKP(0)
    , fIsWarmedUp(false) {
    for (int i = 0; i < FLAGS_skps.count(); i++) {
        if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
            fSKPs.push_back() = FLAGS_skps[i];
        } else {
            SkOSFile::Iter it(FLAGS_skps[i], ".skp");
            SkString path;
            while (it.next(&path)) {
                fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str());
            }
        }
    }

    // seed with an initial benchmark
    // NOTE the initial benchmark will not have preTimingHooks called, but that is okay because
    // it is the warmupbench
    this->next();
}

bool VisualBenchmarkStream::ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) {
    // Not strictly necessary, as it will be checked again later,
    // but helps to avoid a lot of pointless work if we're going to skip it.
    if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) {
        return false;
    }

    SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
    if (stream.get() == nullptr) {
        SkDebugf("Could not read %s.\n", path);
        return false;
    }

    pic->reset(SkPicture::CreateFromStream(stream.get()));
    if (pic->get() == nullptr) {
        SkDebugf("Could not read %s as an SkPicture.\n", path);
        return false;
    }
    return true;
}

Benchmark* VisualBenchmarkStream::next() {
    Benchmark* bench;
    if (!fIsWarmedUp) {
        fIsWarmedUp = true;
        bench = new WarmupBench;
    } else {
        // skips non matching benches
        while ((bench = this->innerNext()) &&
               (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName()) ||
                !bench->isSuitableFor(Benchmark::kGPU_Backend))) {
            bench->unref();
        }
    }

    // TODO move this all to --config
    if (bench && FLAGS_cpu) {
        bench = new CpuWrappedBenchmark(bench);
    } else if (bench && FLAGS_nvpr) {
        bench = new NvprWrappedBenchmark(bench, 4);
    }

    fBenchmark.reset(bench);
    return fBenchmark;
}

Benchmark* VisualBenchmarkStream::innerNext() {
    while (fBenches) {
        Benchmark* bench = fBenches->factory()(nullptr);
        fBenches = fBenches->next();
        if (bench->isVisual()) {
            fSourceType = "bench";
            fBenchType  = "micro";
            return bench;
        }
        bench->unref();
    }

    while (fGMs) {
        SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr));
        fGMs = fGMs->next();
        if (gm->runAsBench()) {
            fSourceType = "gm";
            fBenchType  = "micro";
            return new GMBench(gm.detach());
        }
    }

    // Render skps
    while (fCurrentSKP < fSKPs.count()) {
        const SkString& path = fSKPs[fCurrentSKP++];
        SkAutoTUnref<SkPicture> pic;
        if (!ReadPicture(path.c_str(), &pic)) {
            continue;
        }

        SkString name = SkOSPath::Basename(path.c_str());
        fSourceType = "skp";
        fBenchType = "playback";
        return new VisualSKPBench(name.c_str(), pic.get());
    }

    return nullptr;
}
