/*
 * 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 "SkCanvas.h"
#include "SkCommandLineFlags.h"
#include "SkDocument.h"
#include "SkForceLinking.h"
#include "SkGraphics.h"
#include "SkMD5.h"
#include "SkOSFile.h"
#include "SkPicture.h"
#include "SkStream.h"
#include "SkTArray.h"
#include "SkTSort.h"

static const char kUsage[] =
    "This program takes a list of Skia Picture (SKP) files and renders\n"
    "each as a multipage PDF, then prints out the MD5 checksum of the\n"
    "PDF file.  This can be used to verify that changes to the PDF\n"
    "backend will not change PDF output.\n";

__SK_FORCE_IMAGE_DECODER_LINKING;

DEFINE_string2(inputPaths,
               r,
               "",
               "A list of directories and files to use as input.\n"
               "Files are expected to have the .skp extension.");

static const char SKP_FILE_EXTENSION[] = ".skp";

// Used by SkTQSort<SkString>()
static bool operator<(const SkString& a, const SkString& b) {
    return strcmp(a.c_str(), b.c_str()) < 0;
}

// Process --inputPaths defined on the command line.  Return false if
// no files found.
static bool process_input_files(SkTArray<SkString>* files) {
    for (int i = 0; i < FLAGS_inputPaths.count(); i++) {
        const char* input = FLAGS_inputPaths[i];
        if (sk_isdir(input)) {
            SkOSFile::Iter iter(input, SKP_FILE_EXTENSION);
            SkString inputFilename;
            while (iter.next(&inputFilename)) {
                files->push_back(SkOSPath::Join(input, inputFilename.c_str()));
            }
        } else {
            if (SkStrEndsWith(input, SKP_FILE_EXTENSION)) {
                if (sk_exists(input)) {
                    files->push_back(SkString(input));
                } else {
                    SkDebugf("file_does_not_exist %s\n", input);
                }
            } else {
                SkDebugf("skipping_file %s\n", input);
            }
        }
    }
    if (files->count() > 0) {
        SkTQSort<SkString>(files->begin(), files->end() - 1);
        return true;
    }
    return false;
}

// Print the given SkPicture to a PDF, breaking on 8.5x11 pages.
static void picture_to_pdf(const SkPicture& picture, SkWStream* out) {
    SkAutoTUnref<SkDocument> pdfDocument(SkDocument::CreatePDF(out));

    int width = picture.cullRect().width();
    int height = picture.cullRect().height();

    const int kLetterWidth = 612;   // 8.5 * 72
    const int kLetterHeight = 792;  // 11 * 72
    SkRect letterRect = SkRect::MakeWH(SkIntToScalar(kLetterWidth),
                                       SkIntToScalar(kLetterHeight));

    int xPages = ((width - 1) / kLetterWidth) + 1;
    int yPages = ((height - 1) / kLetterHeight) + 1;

    for (int y = 0; y < yPages; ++y) {
        for (int x = 0; x < xPages; ++x) {
            int w = SkTMin(kLetterWidth, width - (x * kLetterWidth));
            int h = SkTMin(kLetterHeight, height - (y * kLetterHeight));
            SkCanvas* canvas = pdfDocument->beginPage(w, h);
            canvas->clipRect(letterRect);
            canvas->translate(SkIntToScalar(-kLetterWidth * x),
                              SkIntToScalar(-kLetterHeight * y));
            canvas->drawPicture(&picture);
            canvas->flush();
            pdfDocument->endPage();
        }
    }
    pdfDocument->close();
    out->flush();
}

static bool skp_to_pdf_md5(SkStream* input, SkMD5::Digest* digest) {
    SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(input));
    if (NULL == picture.get()) {
        return false;
    }

    SkMD5 checksumWStream;
    picture_to_pdf(*picture, &checksumWStream);
    checksumWStream.finish(*digest);
    return true;
}

SkString digest_to_hex(const SkMD5::Digest& digest) {
    static const char kHex[] = "0123456789ABCDEF";
    SkString string(2 * sizeof(digest.data));
    char* p = string.writable_str();
    for (size_t i = 0; i < sizeof(digest.data); ++i) {
        uint8_t c = digest.data[i];
        *(p++) = kHex[c >> 4];
        *(p++) = kHex[c & 0xF];
    }
    return string;
}

int main(int argc, char** argv) {
    SkCommandLineFlags::SetUsage(kUsage);
    SkCommandLineFlags::Parse(argc, argv);
    SkAutoGraphics ag;
    int successCount = 0;
    SkTArray<SkString> files;
    if (!process_input_files(&files)) {
        SkDebugf("You need to specify a --inputPaths option.\n");
        return 1;
    }
    for (int i = 0; i < files.count(); ++i) {
        SkString basename = SkOSPath::Basename(files[i].c_str());
        SkFILEStream inputStream(files[i].c_str());
        if (!inputStream.isValid()) {
            SkDebugf("could_not_open %s\n", basename.c_str());
            continue;
        }
        SkMD5::Digest digest;
        if (!skp_to_pdf_md5(&inputStream, &digest)) {
            SkDebugf("invalid_skp %s\n", basename.c_str());
            continue;
        }
        SkString hexDigest = digest_to_hex(digest);
        printf("%s %s\n", hexDigest.c_str(), basename.c_str());
        ++successCount;
    }
    return successCount == files.count() ? 0 : 1;
}
