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

#include "LazyDecodeBitmap.h"
#include "CopyTilesRenderer.h"
#include "SkBitmap.h"
#include "SkDevice.h"
#include "SkCommandLineFlags.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkMath.h"
#include "SkOSFile.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"
#include "SkStream.h"
#include "SkString.h"

#include "image_expectations.h"
#include "PictureRenderer.h"
#include "PictureRenderingFlags.h"
#include "picture_utils.h"

// Flags used by this file, alphabetically:
DECLARE_bool(deferImageDecoding);
DEFINE_int32(maxComponentDiff, 256, "Maximum diff on a component, 0 - 256. Components that differ "
             "by more than this amount are considered errors, though all diffs are reported. "
             "Requires --validate.");
DEFINE_string(mismatchPath, "", "Write images for tests that failed due to "
              "pixel mismatches into this directory.");
DEFINE_string(readJsonSummaryPath, "", "JSON file to read image expectations from.");
DECLARE_string(readPath);
DEFINE_bool(writeChecksumBasedFilenames, false,
            "When writing out images, use checksum-based filenames.");
DEFINE_bool(writeEncodedImages, false, "Any time the skp contains an encoded image, write it to a "
            "file rather than decoding it. Requires writePath to be set. Skips drawing the full "
            "skp to a file. Not compatible with deferImageDecoding.");
DEFINE_string(writeJsonSummaryPath, "", "File to write a JSON summary of image results to.");
DEFINE_string2(writePath, w, "", "Directory to write the rendered images into.");
DEFINE_bool(writeWholeImage, false, "In tile mode, write the entire rendered image to a "
            "file, instead of an image for each tile.");
DEFINE_bool(validate, false, "Verify that the rendered image contains the same pixels as "
            "the picture rendered in simple mode. When used in conjunction with --bbh, results "
            "are validated against the picture rendered in the same mode, but without the bbh.");

DEFINE_bool(bench_record, false, "If true, drop into an infinite loop of recording the picture.");

DEFINE_bool(preprocess, false, "If true, perform device specific preprocessing before rendering.");

////////////////////////////////////////////////////////////////////////////////////////////////////

/**
 *  Table for translating from format of data to a suffix.
 */
struct Format {
    SkImageDecoder::Format  fFormat;
    const char*             fSuffix;
};
static const Format gFormats[] = {
    { SkImageDecoder::kBMP_Format, ".bmp" },
    { SkImageDecoder::kGIF_Format, ".gif" },
    { SkImageDecoder::kICO_Format, ".ico" },
    { SkImageDecoder::kJPEG_Format, ".jpg" },
    { SkImageDecoder::kPNG_Format, ".png" },
    { SkImageDecoder::kWBMP_Format, ".wbmp" },
    { SkImageDecoder::kWEBP_Format, ".webp" },
    { SkImageDecoder::kUnknown_Format, "" },
};

/**
 *  Get an appropriate suffix for an image format.
 */
static const char* get_suffix_from_format(SkImageDecoder::Format format) {
    for (size_t i = 0; i < SK_ARRAY_COUNT(gFormats); i++) {
        if (gFormats[i].fFormat == format) {
            return gFormats[i].fSuffix;
        }
    }
    return "";
}

/**
 *  Base name for an image file created from the encoded data in an skp.
 */
static SkString gInputFileName;

/**
 *  Number to be appended to the image file name so that it is unique.
 */
static uint32_t gImageNo;

/**
 *  Set up the name for writing encoded data to a file.
 *  Sets gInputFileName to name, minus any extension ".*"
 *  Sets gImageNo to 0, so images from file "X.skp" will
 *  look like "X_<gImageNo>.<suffix>", beginning with 0
 *  for each new skp.
 */
static void reset_image_file_base_name(const SkString& name) {
    gImageNo = 0;
    // Remove ".skp"
    const char* cName = name.c_str();
    const char* dot = strrchr(cName, '.');
    if (dot != NULL) {
        gInputFileName.set(cName, dot - cName);
    } else {
        gInputFileName.set(name);
    }
}

/**
 *  Write the raw encoded bitmap data to a file.
 */
static bool write_image_to_file(const void* buffer, size_t size, SkBitmap* bitmap) {
    SkASSERT(!FLAGS_writePath.isEmpty());
    SkMemoryStream memStream(buffer, size);
    SkString outPath;
    SkImageDecoder::Format format = SkImageDecoder::GetStreamFormat(&memStream);
    SkString name = SkStringPrintf("%s_%d%s", gInputFileName.c_str(), gImageNo++,
                                   get_suffix_from_format(format));
    SkString dir(FLAGS_writePath[0]);
    outPath = SkOSPath::SkPathJoin(dir.c_str(), name.c_str());
    SkFILEWStream fileStream(outPath.c_str());
    if (!(fileStream.isValid() && fileStream.write(buffer, size))) {
        SkDebugf("Failed to write encoded data to \"%s\"\n", outPath.c_str());
    }
    // Put in a dummy bitmap.
    return SkImageDecoder::DecodeStream(&memStream, bitmap, kUnknown_SkColorType,
                                        SkImageDecoder::kDecodeBounds_Mode);
}

////////////////////////////////////////////////////////////////////////////////////////////////////

/**
 * Called only by render_picture().
 */
static bool render_picture_internal(const SkString& inputPath, const SkString* writePath,
                                    const SkString* mismatchPath,
                                    sk_tools::PictureRenderer& renderer,
                                    SkBitmap** out) {
    SkString inputFilename = SkOSPath::SkBasename(inputPath.c_str());
    SkString writePathString;
    if (NULL != writePath && writePath->size() > 0 && !FLAGS_writeEncodedImages) {
        writePathString.set(*writePath);
    }
    SkString mismatchPathString;
    if (NULL != mismatchPath && mismatchPath->size() > 0) {
        mismatchPathString.set(*mismatchPath);
    }

    SkFILEStream inputStream;
    inputStream.setPath(inputPath.c_str());
    if (!inputStream.isValid()) {
        SkDebugf("Could not open file %s\n", inputPath.c_str());
        return false;
    }

    SkPicture::InstallPixelRefProc proc;
    if (FLAGS_deferImageDecoding) {
        proc = &sk_tools::LazyDecodeBitmap;
    } else if (FLAGS_writeEncodedImages) {
        SkASSERT(!FLAGS_writePath.isEmpty());
        reset_image_file_base_name(inputFilename);
        proc = &write_image_to_file;
    } else {
        proc = &SkImageDecoder::DecodeMemory;
    }

    SkDebugf("deserializing... %s\n", inputPath.c_str());

    SkPicture* picture = SkPicture::CreateFromStream(&inputStream, proc);

    if (NULL == picture) {
        SkDebugf("Could not read an SkPicture from %s\n", inputPath.c_str());
        return false;
    }

    while (FLAGS_bench_record) {
        SkPictureRecorder recorder;
        picture->draw(recorder.beginRecording(picture->width(), picture->height(), NULL, 0));
        SkAutoTUnref<SkPicture> other(recorder.endRecording());
    }

    SkDebugf("drawing... [%i %i] %s\n", picture->width(), picture->height(),
             inputPath.c_str());

    renderer.init(picture, &writePathString, &mismatchPathString, &inputFilename,
                  FLAGS_writeChecksumBasedFilenames);

    if (FLAGS_preprocess) {
        if (NULL != renderer.getCanvas()) {
            renderer.getCanvas()->EXPERIMENTAL_optimize(renderer.getPicture());
        }
    }

    renderer.setup();
    renderer.enableWrites();

    bool success = renderer.render(out);
    if (!success) {
        SkDebugf("Failed to render %s\n", inputFilename.c_str());
    }

    renderer.end();

    SkDELETE(picture);
    return success;
}

static inline int getByte(uint32_t value, int index) {
    SkASSERT(0 <= index && index < 4);
    return (value >> (index * 8)) & 0xFF;
}

static int MaxByteDiff(uint32_t v1, uint32_t v2) {
    return SkMax32(SkMax32(abs(getByte(v1, 0) - getByte(v2, 0)), abs(getByte(v1, 1) - getByte(v2, 1))),
                   SkMax32(abs(getByte(v1, 2) - getByte(v2, 2)), abs(getByte(v1, 3) - getByte(v2, 3))));
}

class AutoRestoreBbhType {
public:
    AutoRestoreBbhType() {
        fRenderer = NULL;
        fSavedBbhType = sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
    }

    void set(sk_tools::PictureRenderer* renderer,
             sk_tools::PictureRenderer::BBoxHierarchyType bbhType) {
        fRenderer = renderer;
        fSavedBbhType = renderer->getBBoxHierarchyType();
        renderer->setBBoxHierarchyType(bbhType);
    }

    ~AutoRestoreBbhType() {
        if (NULL != fRenderer) {
            fRenderer->setBBoxHierarchyType(fSavedBbhType);
        }
    }

private:
    sk_tools::PictureRenderer* fRenderer;
    sk_tools::PictureRenderer::BBoxHierarchyType fSavedBbhType;
};

/**
 * Render the SKP file(s) within inputPath.
 *
 * @param inputPath path to an individual SKP file, or a directory of SKP files
 * @param writePath if not NULL, write all image(s) generated into this directory
 * @param mismatchPath if not NULL, write any image(s) not matching expectations into this directory
 * @param renderer PictureRenderer to use to render the SKPs
 * @param jsonSummaryPtr if not NULL, add the image(s) generated to this summary
 */
static bool render_picture(const SkString& inputPath, const SkString* writePath,
                           const SkString* mismatchPath, sk_tools::PictureRenderer& renderer,
                           sk_tools::ImageResultsAndExpectations *jsonSummaryPtr) {
    int diffs[256] = {0};
    SkBitmap* bitmap = NULL;
    renderer.setJsonSummaryPtr(jsonSummaryPtr);
    bool success = render_picture_internal(inputPath,
        FLAGS_writeWholeImage ? NULL : writePath,
        FLAGS_writeWholeImage ? NULL : mismatchPath,
        renderer,
        FLAGS_validate || FLAGS_writeWholeImage ? &bitmap : NULL);

    if (!success || ((FLAGS_validate || FLAGS_writeWholeImage) && bitmap == NULL)) {
        SkDebugf("Failed to draw the picture.\n");
        SkDELETE(bitmap);
        return false;
    }

    if (FLAGS_validate) {
        SkBitmap* referenceBitmap = NULL;
        sk_tools::PictureRenderer* referenceRenderer;
        // If the renderer uses a BBoxHierarchy, then the reference renderer
        // will be the same renderer, without the bbh.
        AutoRestoreBbhType arbbh;
        if (sk_tools::PictureRenderer::kNone_BBoxHierarchyType !=
            renderer.getBBoxHierarchyType()) {
            referenceRenderer = &renderer;
            referenceRenderer->ref();  // to match auto unref below
            arbbh.set(referenceRenderer, sk_tools::PictureRenderer::kNone_BBoxHierarchyType);
        } else {
            referenceRenderer = SkNEW(sk_tools::SimplePictureRenderer);
        }
        SkAutoTUnref<sk_tools::PictureRenderer> aurReferenceRenderer(referenceRenderer);

        success = render_picture_internal(inputPath, NULL, NULL, *referenceRenderer,
                                          &referenceBitmap);

        if (!success || NULL == referenceBitmap || NULL == referenceBitmap->getPixels()) {
            SkDebugf("Failed to draw the reference picture.\n");
            SkDELETE(bitmap);
            SkDELETE(referenceBitmap);
            return false;
        }

        if (success && (bitmap->width() != referenceBitmap->width())) {
            SkDebugf("Expected image width: %i, actual image width %i.\n",
                     referenceBitmap->width(), bitmap->width());
            SkDELETE(bitmap);
            SkDELETE(referenceBitmap);
            return false;
        }
        if (success && (bitmap->height() != referenceBitmap->height())) {
            SkDebugf("Expected image height: %i, actual image height %i",
                     referenceBitmap->height(), bitmap->height());
            SkDELETE(bitmap);
            SkDELETE(referenceBitmap);
            return false;
        }

        for (int y = 0; success && y < bitmap->height(); y++) {
            for (int x = 0; success && x < bitmap->width(); x++) {
                int diff = MaxByteDiff(*referenceBitmap->getAddr32(x, y),
                                       *bitmap->getAddr32(x, y));
                SkASSERT(diff >= 0 && diff <= 255);
                diffs[diff]++;

                if (diff > FLAGS_maxComponentDiff) {
                    SkDebugf("Expected pixel at (%i %i) exceedds maximum "
                                 "component diff of %i: 0x%x, actual 0x%x\n",
                             x, y, FLAGS_maxComponentDiff,
                             *referenceBitmap->getAddr32(x, y),
                             *bitmap->getAddr32(x, y));
                    SkDELETE(bitmap);
                    SkDELETE(referenceBitmap);
                    return false;
                }
            }
        }
        SkDELETE(referenceBitmap);

        for (int i = 1; i <= 255; ++i) {
            if(diffs[i] > 0) {
                SkDebugf("Number of pixels with max diff of %i is %i\n", i, diffs[i]);
            }
        }
    }

    if (FLAGS_writeWholeImage) {
        sk_tools::force_all_opaque(*bitmap);

        SkString inputFilename = SkOSPath::SkBasename(inputPath.c_str());
        SkString outputFilename(inputFilename);
        sk_tools::replace_char(&outputFilename, '.', '_');
        outputFilename.append(".png");

        if (NULL != jsonSummaryPtr) {
            sk_tools::ImageDigest imageDigest(*bitmap);
            jsonSummaryPtr->add(inputFilename.c_str(), outputFilename.c_str(), imageDigest);
            if ((NULL != mismatchPath) && !mismatchPath->isEmpty() &&
                !jsonSummaryPtr->matchesExpectation(inputFilename.c_str(), imageDigest)) {
                success &= sk_tools::write_bitmap_to_disk(*bitmap, *mismatchPath, NULL,
                                                          outputFilename);
            }
        }

        if ((NULL != writePath) && !writePath->isEmpty()) {
            success &= sk_tools::write_bitmap_to_disk(*bitmap, *writePath, NULL, outputFilename);
        }
    }
    SkDELETE(bitmap);

    return success;
}


static int process_input(const char* input, const SkString* writePath,
                         const SkString* mismatchPath, sk_tools::PictureRenderer& renderer,
                         sk_tools::ImageResultsAndExpectations *jsonSummaryPtr) {
    SkOSFile::Iter iter(input, "skp");
    SkString inputFilename;
    int failures = 0;
    SkDebugf("process_input, %s\n", input);
    if (iter.next(&inputFilename)) {
        do {
            SkString inputPath = SkOSPath::SkPathJoin(input, inputFilename.c_str());
            if (!render_picture(inputPath, writePath, mismatchPath, renderer, jsonSummaryPtr)) {
                ++failures;
            }
        } while(iter.next(&inputFilename));
    } else if (SkStrEndsWith(input, ".skp")) {
        SkString inputPath(input);
        if (!render_picture(inputPath, writePath, mismatchPath, renderer, jsonSummaryPtr)) {
            ++failures;
        }
    } else {
        SkString warning;
        warning.printf("Warning: skipping %s\n", input);
        SkDebugf(warning.c_str());
    }
    return failures;
}

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

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

    if (FLAGS_maxComponentDiff < 0 || FLAGS_maxComponentDiff > 256) {
        SkDebugf("--maxComponentDiff must be between 0 and 256\n");
        exit(-1);
    }

    if (FLAGS_maxComponentDiff != 256 && !FLAGS_validate) {
        SkDebugf("--maxComponentDiff requires --validate\n");
        exit(-1);
    }

    if (FLAGS_writeEncodedImages) {
        if (FLAGS_writePath.isEmpty()) {
            SkDebugf("--writeEncodedImages requires --writePath\n");
            exit(-1);
        }
        if (FLAGS_deferImageDecoding) {
            SkDebugf("--writeEncodedImages is not compatible with --deferImageDecoding\n");
            exit(-1);
        }
    }

    SkString errorString;
    SkAutoTUnref<sk_tools::PictureRenderer> renderer(parseRenderer(errorString,
                                                                   kRender_PictureTool));
    if (errorString.size() > 0) {
        SkDebugf("%s\n", errorString.c_str());
    }

    if (renderer.get() == NULL) {
        exit(-1);
    }

    SkAutoGraphics ag;

    SkString writePath;
    if (FLAGS_writePath.count() == 1) {
        writePath.set(FLAGS_writePath[0]);
    }
    SkString mismatchPath;
    if (FLAGS_mismatchPath.count() == 1) {
        mismatchPath.set(FLAGS_mismatchPath[0]);
    }
    sk_tools::ImageResultsAndExpectations jsonSummary;
    sk_tools::ImageResultsAndExpectations* jsonSummaryPtr = NULL;
    if (FLAGS_writeJsonSummaryPath.count() == 1) {
        jsonSummaryPtr = &jsonSummary;
        if (FLAGS_readJsonSummaryPath.count() == 1) {
            SkASSERT(jsonSummary.readExpectationsFile(FLAGS_readJsonSummaryPath[0]));
        }
    }

    int failures = 0;
    for (int i = 0; i < FLAGS_readPath.count(); i ++) {
        failures += process_input(FLAGS_readPath[i], &writePath, &mismatchPath, *renderer.get(),
                                  jsonSummaryPtr);
    }
    if (failures != 0) {
        SkDebugf("Failed to render %i pictures.\n", failures);
        return 1;
    }
#if SK_SUPPORT_GPU
#if GR_CACHE_STATS
    if (renderer->isUsingGpuDevice()) {
        GrContext* ctx = renderer->getGrContext();
        ctx->printCacheStats();
#ifdef SK_DEVELOPER
        ctx->dumpFontCache();
#endif
    }
#endif
#endif
    if (FLAGS_writeJsonSummaryPath.count() == 1) {
        jsonSummary.writeToFile(FLAGS_writeJsonSummaryPath[0]);
    }
    return 0;
}

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