/*
 * Copyright 2018 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 "SkData.h"
#include "SkJSON.h"
#include "SkStream.h"

#if defined(SK_BUILD_FOR_ANDROID)
static constexpr const char* kBenchFile = "/data/local/tmp/bench.json";
#else
static constexpr const char* kBenchFile = "/tmp/bench.json";
#endif

class JsonBench : public Benchmark {
public:

protected:
    const char* onGetName() override { return "json_skjson"; }

    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }

    void onPerCanvasPreDraw(SkCanvas*) override {
        fData = SkData::MakeFromFileName(kBenchFile);
        if (!fData) {
            SkDebugf("!! Could not open bench file: %s\n", kBenchFile);
        }
    }

    void onPerCanvasPostDraw(SkCanvas*) override {
        fData = nullptr;
    }

    void onDraw(int loops, SkCanvas*) override {
        if (!fData) return;

        for (int i = 0; i < loops; i++) {
            skjson::DOM dom(static_cast<const char*>(fData->data()), fData->size());
            if (dom.root().is<skjson::NullValue>()) {
                SkDebugf("!! Parsing failed.\n");
                return;
            }
        }
    }

private:
    sk_sp<SkData> fData;

    using INHERITED = Benchmark;
};

DEF_BENCH( return new JsonBench; )

#if (0)

#include "rapidjson/document.h"

class RapidJsonBench : public Benchmark {
public:

protected:
    const char* onGetName() override { return "json_rapidjson"; }

    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }

    void onPerCanvasPreDraw(SkCanvas*) override {
        if (auto stream = SkStream::MakeFromFile(kBenchFile)) {
            SkASSERT(stream->hasLength());
            fCStringData = SkData::MakeUninitialized(stream->getLength() + 1);
            auto* data8 = reinterpret_cast<uint8_t*>(fCStringData->writable_data());
            SkAssertResult(stream->read(data8, stream->getLength()) == stream->getLength());
            data8[stream->getLength()] = '\0';

        } else {
            SkDebugf("!! Could not open bench file: %s\n", kBenchFile);
        }
    }

    void onPerCanvasPostDraw(SkCanvas*) override {
        fCStringData = nullptr;
    }

    void onDraw(int loops, SkCanvas*) override {
        if (!fCStringData) return;

        for (int i = 0; i < loops; i++) {
            rapidjson::Document doc;
            doc.Parse(static_cast<const char*>(fCStringData->data()));
            if (doc.HasParseError()) {
                SkDebugf("!! Parsing failed.\n");
                return;
            }
        }
    }

private:
    sk_sp<SkData> fCStringData;

    using INHERITED = Benchmark;
};

DEF_BENCH( return new RapidJsonBench; )

#endif

#if (0)

#include "pjson.h"

class PJsonBench : public Benchmark {
public:

protected:
    const char* onGetName() override { return "json_pjson"; }

    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }

    void onPerCanvasPreDraw(SkCanvas*) override {
        if (auto stream = SkStream::MakeFromFile(kBenchFile)) {
            SkASSERT(stream->hasLength());
            fCStringData = SkData::MakeUninitialized(stream->getLength() + 1);
            auto* data8 = reinterpret_cast<uint8_t*>(fCStringData->writable_data());
            SkAssertResult(stream->read(data8, stream->getLength()) == stream->getLength());
            data8[stream->getLength()] = '\0';

        } else {
            SkDebugf("!! Could not open bench file: %s\n", kBenchFile);
        }
    }

    void onPerCanvasPostDraw(SkCanvas*) override {
        fCStringData = nullptr;
    }

    void onDraw(int loops, SkCanvas*) override {
        if (!fCStringData) return;

        for (int i = 0; i < loops; i++) {
            // Copy needed for in-place operation.
            auto data = SkData::MakeWithCopy(fCStringData->data(), fCStringData->size());
            pjson::document doc;
            if (!doc.deserialize_in_place(static_cast<char*>(data->writable_data()))) {
                SkDebugf("!! Parsing failed.\n");
                return;
            }
        }
    }

private:
    sk_sp<SkData> fCStringData;

    using INHERITED = Benchmark;
};

DEF_BENCH( return new PJsonBench; )

#endif
