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

#include "include/core/SkBitmap.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkSerialProcs.h"
#include "include/core/SkStream.h"
#include "include/encode/SkPngEncoder.h"
#include "src/core/SkPicturePriv.h"
#include "src/core/SkRecord.h"
#include "src/core/SkRecordCanvas.h"
#include "src/core/SkRecordDraw.h"
#include "src/core/SkRecordOpts.h"
#include "src/core/SkTime.h"
#include "src/image/SkImage_Base.h"
#include "tools/dump_base.h"
#include "tools/flags/CommandLineFlags.h"

#include <cstdio>

static DEFINE_string2(skps, r, "", ".SKPs to dump.");
static DEFINE_string(match, "", "The usual filters on file names to dump.");
static DEFINE_bool2(optimize, O, false, "Run SkRecordOptimize before dumping.");
static DEFINE_int(tile, 1000000000, "Simulated tile size.");
static DEFINE_bool(timeWithCommand, false,
                   "If true, print time next to command, else in first column.");
static DEFINE_string2(write, w, "", "Write the (optimized) picture to the named file.");

int main(int argc, char** argv) {
    CommandLineFlags::Parse(argc, argv);

    for (int i = 0; i < FLAGS_skps.size(); i++) {
        if (CommandLineFlags::ShouldSkip(FLAGS_match, FLAGS_skps[i])) {
            continue;
        }

        std::unique_ptr<SkStream> stream = SkStream::MakeFromFile(FLAGS_skps[i]);
        if (!stream) {
            SkDebugf("Could not read %s.\n", FLAGS_skps[i]);
            return 1;
        }
        sk_sp<SkPicture> src(SkPicture::MakeFromStream(stream.get()));
        if (!src) {
            SkDebugf("Could not read %s as an SkPicture.\n", FLAGS_skps[i]);
            return 1;
        }
        const int w = SkScalarCeilToInt(src->cullRect().width());
        const int h = SkScalarCeilToInt(src->cullRect().height());

        SkRecord record;
        SkRecordCanvas rec(&record, w, h);
        src->playback(&rec);

        if (FLAGS_optimize) {
            SkRecordOptimize(&record);
        }

        SkBitmap bitmap;
        bitmap.allocN32Pixels(w, h);
        SkCanvas canvas(bitmap);
        canvas.clipRect(SkRect::MakeWH(SkIntToScalar(FLAGS_tile),
                                       SkIntToScalar(FLAGS_tile)));

        printf("%s %s\n", FLAGS_optimize ? "optimized" : "not-optimized", FLAGS_skps[i]);

        SkRecordDumper dumper(&canvas, record.count());
        for (int j = 0; j < record.count(); j++) {
            record.visit(j, dumper);
        }

        if (FLAGS_write.size() > 0) {
            SkPictureRecorder r;
            SkRecordDraw(record,
                         r.beginRecording(SkRect::MakeIWH(w, h)),
                         nullptr,
                         nullptr,
                         0,
                         nullptr,
                         nullptr);
            sk_sp<SkPicture> dst(r.finishRecordingAsPicture());
            SkFILEWStream ostream(FLAGS_write[0]);
            SkSerialProcs sProcs;
            sProcs.fImageProc = [](SkImage* img, void*) -> SkSerialReturnType {
                return SkPngEncoder::Encode(nullptr, img, SkPngEncoder::Options{});
            };
            dst->serialize(&ostream, &sProcs);
        }
    }

    return 0;
}
