/*
 * 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 "SkBitmapDevice.h"
#include "SkCanvas.h"
#include "SkCommandLineFlags.h"
#include "SkDevice.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkOSFile.h"
#include "SkPdfConfig.h"
#include "SkPdfRenderer.h"
#include "SkPicture.h"
#include "SkStream.h"
#include "SkTypeface.h"
#include "SkTArray.h"
#include "SkNulCanvas.h"

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

DEFINE_string2(readPath, r, "", "pdf files or directories of pdf files to process.");
DEFINE_string2(writePath, w, "", "Directory to write the rendered pages.");
DEFINE_bool2(noExtensionForOnePagePdf, n, false, "No page extension if only one page.");
DEFINE_bool2(showMemoryUsage, m, false, "Show Memory usage.");
DEFINE_string2(pages, p, "all", "What pages to render and how:\n"
                                "\tall - all pages\n"
                                "\treverse - all pages, in reverse order\n"
                                "\tfirst - first page\n"
                                "\tlast - last page\n"
                                "\tnumber - a specific page number\n"
               );
DEFINE_double(DPI, 72, "DPI to be used for rendering (scale).");
DEFINE_int32(benchLoad, 0, "Load the pdf file minimally N times, without any rendering and \n"
             "\tminimal parsing to ensure correctness. Default 0 (disabled).");
DEFINE_int32(benchRender, 0, "Render the pdf content N times. Default 0 (disabled)");
#if SK_SUPPORT_GPU
DEFINE_string2(config, c, "8888", "Canvas to render:\n"
                                  "\t8888 - argb\n"
                                  "\tgpu: use the gpu\n"
                                  "\tnul - render in null canvas, any draw will just return.\n"
               );
#else
DEFINE_string2(config, c, "8888", "Canvas to render:\n"
                                  "\t8888 - argb\n"
                                  "\tnul - render in null canvas, any draw will just return.\n"
               );
#endif
DEFINE_bool2(transparentBackground, t, false, "Make background transparent instead of white.");

/**
 * Given list of directories and files to use as input, expects to find .pdf
 * files and it will convert them to .png files writing them in the same directory
 * one file for each page.
 *
 * Returns zero exit code if all .pdf files were converted successfully,
 * otherwise returns error code 1.
 */

static const char PDF_FILE_EXTENSION[] = "pdf";
static const char PNG_FILE_EXTENSION[] = "png";

/** Replaces the extension of a file.
 * @param path File name whose extension will be changed.
 * @param old_extension The old extension.
 * @param new_extension The new extension.
 * @returns false if the file did not has the expected extension.
 *  if false is returned, contents of path are undefined.
 */
static bool add_page_and_replace_filename_extension(SkString* path, int page,
                                       const char old_extension[],
                                       const char new_extension[]) {
    if (path->endsWith(old_extension)) {
        path->remove(path->size() - strlen(old_extension),
                     strlen(old_extension));
        if (!path->endsWith(".")) {
            return false;
        }
        if (page >= 0) {
            path->appendf("%i.", page);
        }
        path->append(new_extension);
        return true;
    }
    return false;
}

/** Builds the output filename. path = dir/name, and it replaces expected
 * .skp extension with .pdf extention.
 * @param path Output filename.
 * @param name The name of the file.
 * @returns false if the file did not has the expected extension.
 *  if false is returned, contents of path are undefined.
 */
static bool make_output_filepath(SkString* path, const SkString& dir,
                                 const SkString& name,
                                 int page) {
    *path = SkOSPath::SkPathJoin(dir.c_str(), name.c_str());
    return add_page_and_replace_filename_extension(path, page,
                                                   PDF_FILE_EXTENSION,
                                                   PNG_FILE_EXTENSION);
}

static void setup_bitmap(SkBitmap* bitmap, int width, int height, SkColor color) {
    bitmap->allocN32Pixels(width, height);
    bitmap->eraseColor(color);
}

/** Write the output of pdf renderer to a file.
 * @param outputDir Output dir.
 * @param inputFilename The skp file that was read.
 * @param renderer The object responsible to write the pdf file.
 * @param page -1 means there is only one page (0), and render in a file without page extension
 */

#ifdef PDF_TRACE_DIFF_IN_PNG
extern "C" SkBitmap* gDumpBitmap;
extern "C" SkCanvas* gDumpCanvas;
#endif

#if SK_SUPPORT_GPU
GrContextFactory gContextFactory;
#endif

static bool render_page(const SkString& outputDir,
                        const SkString& inputFilename,
                        const SkPdfRenderer& renderer,
                        int page) {
    SkRect rect = renderer.MediaBox(page < 0 ? 0 :page);

    // Exercise all pdf codepaths as in normal rendering, but no actual bits are changed.
    if (!FLAGS_config.isEmpty() && strcmp(FLAGS_config[0], "nul") == 0) {
        SkBitmap bitmap;
        SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
        SkNulCanvas canvas(device);
        renderer.renderPage(page < 0 ? 0 : page, &canvas, rect);
    } else {
        // 8888
        SkRect rect = renderer.MediaBox(page < 0 ? 0 :page);

        SkBitmap bitmap;
        SkScalar width = SkScalarMul(rect.width(),  SkDoubleToScalar(FLAGS_DPI / 72.0));
        SkScalar height = SkScalarMul(rect.height(),  SkDoubleToScalar(FLAGS_DPI / 72.0));

        rect = SkRect::MakeWH(width, height);

        SkColor background = FLAGS_transparentBackground ? SK_ColorTRANSPARENT : SK_ColorWHITE;

#ifdef PDF_DEBUG_3X
        setup_bitmap(&bitmap, 3 * (int)SkScalarToDouble(width), 3 * (int)SkScalarToDouble(height),
                     background);
#else
        setup_bitmap(&bitmap, (int)SkScalarToDouble(width), (int)SkScalarToDouble(height),
                     background);
#endif
        SkAutoTUnref<SkBaseDevice> device;
        if (strcmp(FLAGS_config[0], "8888") == 0) {
            device.reset(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
        }
#if SK_SUPPORT_GPU
        else if (strcmp(FLAGS_config[0], "gpu") == 0) {
            SkAutoTUnref<GrSurface> target;
            GrContext* gr = gContextFactory.get(GrContextFactory::kNative_GLContextType);
            if (gr) {
                // create a render target to back the device
                GrTextureDesc desc;
                desc.fConfig = kSkia8888_GrPixelConfig;
                desc.fFlags = kRenderTarget_GrTextureFlagBit;
                desc.fWidth = SkScalarCeilToInt(width);
                desc.fHeight = SkScalarCeilToInt(height);
                desc.fSampleCnt = 0;
                target.reset(gr->createUncachedTexture(desc, NULL, 0));
            }
            if (NULL == target.get()) {
                SkASSERT(0);
                return false;
            }

            device.reset(SkGpuDevice::Create(target));
        }
#endif
        else {
            SkDebugf("unknown --config: %s\n", FLAGS_config[0]);
            return false;
        }
        SkCanvas canvas(device);

#ifdef PDF_TRACE_DIFF_IN_PNG
        gDumpBitmap = &bitmap;
        gDumpCanvas = &canvas;
#endif
        renderer.renderPage(page < 0 ? 0 : page, &canvas, rect);

        SkString outputPath;
        if (!make_output_filepath(&outputPath, outputDir, inputFilename, page)) {
            return false;
        }
        SkImageEncoder::EncodeFile(outputPath.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100);

        if (FLAGS_showMemoryUsage) {
            SkDebugf("Memory usage after page %i rendered: %u\n",
                     page < 0 ? 0 : page, (unsigned int)renderer.bytesUsed());
        }
    }
    return true;
}

/** Reads an skp file, renders it to pdf and writes the output to a pdf file
 * @param inputPath The skp file to be read.
 * @param outputDir Output dir.
 */
static bool process_pdf(const SkString& inputPath, const SkString& outputDir) {
    SkDebugf("Loading PDF:  %s\n", inputPath.c_str());

    SkString inputFilename = SkOSPath::SkBasename(inputPath.c_str());

    SkAutoTDelete<SkPdfRenderer> renderer(SkPdfRenderer::CreateFromFile(inputPath.c_str()));
    if (NULL == renderer.get()) {
        SkDebugf("Failure loading file %s\n", inputPath.c_str());
        return false;
    }

    if (FLAGS_showMemoryUsage) {
        SkDebugf("Memory usage after load: %u\n", (unsigned int) renderer->bytesUsed());
    }

    // TODO(edisonn): bench timers
    if (FLAGS_benchLoad > 0) {
        for (int i = 0 ; i < FLAGS_benchLoad; i++) {
            SkAutoTDelete<SkPdfRenderer> benchRenderer(
                    SkPdfRenderer::CreateFromFile(inputPath.c_str()));
            if (NULL == benchRenderer.get()) {
                SkDebugf("Failed to load on %ith attempt\n", i);
            } else if (FLAGS_showMemoryUsage) {
                SkDebugf("Memory usage after load %i number : %u\n", i,
                         (unsigned int) benchRenderer->bytesUsed());
            }
        }
    }

    if (!renderer->pages()) {
        // This should never happen, since CreateFromFile will return NULL if there are no pages.
        SkASSERT(false);
        SkDebugf("ERROR: Empty PDF Document %s\n", inputPath.c_str());
        return false;
    }

    bool success = true;
    for (int i = 0; i < FLAGS_benchRender + 1; i++) {
        // TODO(edisonn) if (i == 1) start timer
        if (strcmp(FLAGS_pages[0], "all") == 0) {
            for (int pn = 0; pn < renderer->pages(); ++pn) {
                success &= render_page(outputDir, inputFilename, *renderer,
                        FLAGS_noExtensionForOnePagePdf && renderer->pages() == 1 ? -1 : pn);
            }
        } else if (strcmp(FLAGS_pages[0], "reverse") == 0) {
            for (int pn = renderer->pages() - 1; pn >= 0; --pn) {
                success &= render_page(outputDir, inputFilename, *renderer,
                        FLAGS_noExtensionForOnePagePdf && renderer->pages() == 1 ? -1 : pn);
            }
        } else if (strcmp(FLAGS_pages[0], "first") == 0) {
            success &= render_page(outputDir, inputFilename, *renderer,
                    FLAGS_noExtensionForOnePagePdf && renderer->pages() == 1 ? -1 : 0);
        } else if (strcmp(FLAGS_pages[0], "last") == 0) {
            success &= render_page(outputDir, inputFilename, *renderer,
                    FLAGS_noExtensionForOnePagePdf && renderer->pages() == 1 ? -1
                    : renderer->pages() - 1);
        } else {
            int pn = atoi(FLAGS_pages[0]);
            success &= render_page(outputDir, inputFilename, *renderer,
                    FLAGS_noExtensionForOnePagePdf && renderer->pages() == 1 ? -1 : pn);
        }
    }

    if (!success) {
        SkDebugf("Failures for file %s\n", inputPath.c_str());
    }

    return success;
}

/** For each file in the directory or for the file passed in input, call
 * parse_pdf.
 * @param input A directory or an pdf file.
 * @param outputDir Output dir.
 */
static int process_input(const char* input, const SkString& outputDir) {
    int failures = 0;
    if (sk_isdir(input)) {
        SkOSFile::Iter iter(input, PDF_FILE_EXTENSION);
        SkString inputFilename;
        while (iter.next(&inputFilename)) {
            SkString inputPath = SkOSPath::SkPathJoin(input, inputFilename.c_str());
            if (!process_pdf(inputPath, outputDir)) {
                ++failures;
            }
        }
    } else {
        SkString inputPath(input);
        if (!process_pdf(inputPath, outputDir)) {
            ++failures;
        }
    }
    return failures;
}

int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
    SkCommandLineFlags::SetUsage("Parse and Render .pdf files (pdf viewer).");
    SkCommandLineFlags::Parse(argc, argv);

    if (FLAGS_readPath.isEmpty()) {
        SkDebugf(".pdf files or directories are required.\n");
        exit(-1);
    }

    SkString outputDir;
    if (FLAGS_writePath.count() == 1) {
        outputDir.set(FLAGS_writePath[0]);
    }

    int failures = 0;
    for (int i = 0; i < FLAGS_readPath.count(); i ++) {
        failures += process_input(FLAGS_readPath[i], outputDir);
    }

    reportPdfRenderStats();

    if (failures != 0) {
        SkDebugf("Failed to render %i PDFs.\n", failures);
        return 1;
    }

    return 0;
}

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