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

#include "BenchTimer.h"
#include "LazyDecodeBitmap.h"
#include "PictureBenchmark.h"
#include "PictureRenderer.h"
#include "SkBenchmark.h"
#include "SkForceLinking.h"
#include "SkGraphics.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkTArray.h"
#include "SkCommandLineFlags.h"

typedef sk_tools::PictureRenderer::BBoxHierarchyType BBoxType;
static const int kBBoxTypeCount = sk_tools::PictureRenderer::kLast_BBoxHierarchyType + 1;


DEFINE_string2(skps, r, "", "The list of SKPs to benchmark.");
DEFINE_string(bb_types, "", "The set of bbox types to test. If empty, all are tested. "
                       "Should be one or more of none, quadtree, rtree, tilegrid.");
DEFINE_int32(record, 100, "Number of times to record each SKP.");
DEFINE_int32(playback, 1, "Number of times to playback each SKP.");
DEFINE_int32(tilesize, 256, "The size of a tile.");

struct Measurement {
    SkString fName;
    double fRecordAverage[kBBoxTypeCount];
    double fPlaybackAverage[kBBoxTypeCount];
};

const char* kBBoxHierarchyTypeNames[kBBoxTypeCount] = {
    "none", // kNone_BBoxHierarchyType
    "quadtree", // kQuadTree_BBoxHierarchyType
    "rtree", // kRTree_BBoxHierarchyType
    "tilegrid", // kTileGrid_BBoxHierarchyType
};

static SkPicture* pic_from_path(const char path[]) {
    SkFILEStream stream(path);
    if (!stream.isValid()) {
        SkDebugf("-- Can't open '%s'\n", path);
        return NULL;
    }
    return SkPicture::CreateFromStream(&stream, &sk_tools::LazyDecodeBitmap);
}

/**
 * This function is the sink to which all work ends up going.
 * @param renderer The renderer to use to perform the work.
 *                 To measure rendering, use a TiledPictureRenderer.
 *                 To measure recording, use a RecordPictureRenderer.
 * @param bBoxType The bounding box hierarchy type to use.
 * @param pic The picture to draw to the renderer.
 * @param numRepeats The number of times to repeat the draw.
 * @param timer The timer used to benchmark the work.
 */
static void do_benchmark_work(sk_tools::PictureRenderer* renderer,
        BBoxType bBoxType,
        SkPicture* pic,
        const int numRepeats,
        BenchTimer* timer) {
    renderer->setBBoxHierarchyType(bBoxType);
    renderer->setGridSize(FLAGS_tilesize, FLAGS_tilesize);
    renderer->init(pic, NULL, NULL, NULL, false);

    SkDebugf("%s %d times...\n", renderer->getConfigName().c_str(), numRepeats);
    for (int i = 0; i < numRepeats; ++i) {
        renderer->setup();
        // Render once to fill caches
        renderer->render();
        // Render again to measure
        timer->start();
        renderer->render();
        timer->end();
    }
}

int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
    SkCommandLineFlags::Parse(argc, argv);
    SkAutoGraphics ag;
    bool includeBBoxType[kBBoxTypeCount];
    for (int bBoxType = 0; bBoxType < kBBoxTypeCount; ++bBoxType) {
        includeBBoxType[bBoxType] = (FLAGS_bb_types.count() == 0) ||
            FLAGS_bb_types.contains(kBBoxHierarchyTypeNames[bBoxType]);
    }
    // go through all the pictures
    SkTArray<Measurement> measurements;
    for (int index = 0; index < FLAGS_skps.count(); ++index) {
        const char* path = FLAGS_skps[index];
        SkPicture* picture = pic_from_path(path);
        if (NULL == picture) {
            SkDebugf("Couldn't create picture. Ignoring path: %s\n", path);
            continue;
        }
        SkDebugf("Benchmarking path: %s\n", path);
        Measurement& measurement = measurements.push_back();
        measurement.fName = path;
        for (int bBoxType = 0; bBoxType < kBBoxTypeCount; ++bBoxType) {
            if (!includeBBoxType[bBoxType]) { continue; }
            if (FLAGS_playback > 0) {
                sk_tools::TiledPictureRenderer playbackRenderer;
                BenchTimer playbackTimer;
                do_benchmark_work(&playbackRenderer, (BBoxType)bBoxType,
                                  picture, FLAGS_playback, &playbackTimer);
                measurement.fPlaybackAverage[bBoxType] = playbackTimer.fCpu;
            }
            if (FLAGS_record > 0) {
                sk_tools::RecordPictureRenderer recordRenderer;
                BenchTimer recordTimer;
                do_benchmark_work(&recordRenderer, (BBoxType)bBoxType,
                                  picture, FLAGS_record, &recordTimer);
                measurement.fRecordAverage[bBoxType] = recordTimer.fCpu;
            }
        }
    }

    Measurement globalMeasurement;
    for (int bBoxType = 0; bBoxType < kBBoxTypeCount; ++bBoxType) {
        if (!includeBBoxType[bBoxType]) { continue; }
        globalMeasurement.fPlaybackAverage[bBoxType] = 0;
        globalMeasurement.fRecordAverage[bBoxType] = 0;
        for (int index = 0; index < measurements.count(); ++index) {
            const Measurement& measurement = measurements[index];
            globalMeasurement.fPlaybackAverage[bBoxType] +=
                measurement.fPlaybackAverage[bBoxType];
            globalMeasurement.fRecordAverage[bBoxType] +=
                measurement.fRecordAverage[bBoxType];
        }
        globalMeasurement.fPlaybackAverage[bBoxType] /= measurements.count();
        globalMeasurement.fRecordAverage[bBoxType] /= measurements.count();
    }

    // Output gnuplot readable histogram data..
    const char* pbTitle = "bbh_shootout_playback.dat";
    const char* recTitle = "bbh_shootout_record.dat";
    SkFILEWStream playbackOut(pbTitle);
    SkFILEWStream recordOut(recTitle);
    recordOut.writeText("# ");
    playbackOut.writeText("# ");
    SkDebugf("---\n");
    for (int bBoxType = 0; bBoxType < kBBoxTypeCount; ++bBoxType) {
        if (!includeBBoxType[bBoxType]) { continue; }
        SkString out;
        out.printf("%s ", kBBoxHierarchyTypeNames[bBoxType]);
        recordOut.writeText(out.c_str());
        playbackOut.writeText(out.c_str());

        if (FLAGS_record > 0) {
            SkDebugf("Average %s recording time: %.3fms\n",
                kBBoxHierarchyTypeNames[bBoxType],
                globalMeasurement.fRecordAverage[bBoxType]);
        }
        if (FLAGS_playback > 0) {
            SkDebugf("Average %s playback time: %.3fms\n",
                kBBoxHierarchyTypeNames[bBoxType],
                globalMeasurement.fPlaybackAverage[bBoxType]);
        }
    }
    recordOut.writeText("\n");
    playbackOut.writeText("\n");
    // Write to file, and save recording averages.
    for (int index = 0; index < measurements.count(); ++index) {
        const Measurement& measurement = measurements[index];
        SkString pbLine;
        SkString recLine;

        pbLine.printf("%d", index);
        recLine.printf("%d", index);
        for (int bBoxType = 0; bBoxType < kBBoxTypeCount; ++bBoxType) {
            if (!includeBBoxType[bBoxType]) { continue; }
            pbLine.appendf(" %f", measurement.fPlaybackAverage[bBoxType]);
            recLine.appendf(" %f", measurement.fRecordAverage[bBoxType]);
        }
        pbLine.appendf("\n");
        recLine.appendf("\n");
        playbackOut.writeText(pbLine.c_str());
        recordOut.writeText(recLine.c_str());
    }
    SkDebugf("\nWrote data to gnuplot-readable files: %s %s\n", pbTitle, recTitle);
    return 0;
}

#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
int main(int argc, char** argv) {
    return tool_main(argc, argv);
}
#endif
