/*
 * 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"

#if SK_SUPPORT_GPU
#include "GrContext.h"
#endif

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.");
DEFINE_bool(warmup, true, "Include a warmup bench? (Excluding the warmup may compromise results)");

// 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);
        fPerlinRect = SkRect::MakeLTRB(0., 0., 400., 400.);
    }
private:
    const char* onGetName() override { return "warmupbench"; }
    SkIPoint onGetSize() override {
        int w = SkScalarCeilToInt(SkTMax(fPath.getBounds().right(), fPerlinRect.right()));
        int h = SkScalarCeilToInt(SkTMax(fPath.getBounds().bottom(), fPerlinRect.bottom()));
        return SkIPoint::Make(w, h);
    }
    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();
        for (int i = 0; i < loops; i++) {
            canvas->drawPath(fPath, paint);
            canvas->drawRect(fPerlinRect, perlinPaint);
#if SK_SUPPORT_GPU
            // Ensure the GrContext doesn't batch across draw loops.
            if (GrContext* context = canvas->getGrContext()) {
                context->flush();
            }
#endif
        }
    }
    SkPath fPath;
    SkRect fPerlinRect;
};

VisualBenchmarkStream::VisualBenchmarkStream(const SkSurfaceProps& surfaceProps, bool justSKP)
    : fSurfaceProps(surfaceProps)
    , 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());
            }
        }
    }

    if (justSKP) {
       fGMs = nullptr;
       fBenches = nullptr;
    }

    // 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();
}

sk_sp<SkPicture> VisualBenchmarkStream::ReadPicture(const char path[]) {
    // 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 nullptr;
    }

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

    auto pic = SkPicture::MakeFromStream(stream.get());
    if (!pic) {
        SkDebugf("Could not read %s as an SkPicture.\n", path);
    }
    return pic;
}

Benchmark* VisualBenchmarkStream::next() {
    Benchmark* bench;
    if (FLAGS_warmup && !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(fSurfaceProps, bench);
    } else if (bench && FLAGS_offscreen) {
        bench = new GpuWrappedBenchmark(fSurfaceProps, bench, FLAGS_msaa);
    }

    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.release());
        }
    }

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

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

    return nullptr;
}
