/*
 * 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 "SkBitmap.h"
#include "SkImageDecoder.h"
#include "SkOSFile.h"
#include "SkRunnable.h"
#include "SkSize.h"
#include "SkStream.h"
#include "SkTDict.h"
#include "SkTaskGroup.h"

// from the tools directory for replace_char(...)
#include "picture_utils.h"

#include "SkDiffContext.h"
#include "SkImageDiffer.h"
#include "skpdiff_util.h"

SkDiffContext::SkDiffContext() {
    fDiffers = NULL;
    fDifferCount = 0;
}

SkDiffContext::~SkDiffContext() {
    if (NULL != fDiffers) {
        SkDELETE_ARRAY(fDiffers);
    }
}

void SkDiffContext::setAlphaMaskDir(const SkString& path) {
    if (!path.isEmpty() && sk_mkdir(path.c_str())) {
        fAlphaMaskDir = path;
    }
}

void SkDiffContext::setRgbDiffDir(const SkString& path) {
    if (!path.isEmpty() && sk_mkdir(path.c_str())) {
        fRgbDiffDir = path;
    }
}

void SkDiffContext::setWhiteDiffDir(const SkString& path) {
    if (!path.isEmpty() && sk_mkdir(path.c_str())) {
        fWhiteDiffDir = path;
    }
}

void SkDiffContext::setLongNames(const bool useLongNames) {
    longNames = useLongNames;
}

void SkDiffContext::setDiffers(const SkTDArray<SkImageDiffer*>& differs) {
    // Delete whatever the last array of differs was
    if (NULL != fDiffers) {
        SkDELETE_ARRAY(fDiffers);
        fDiffers = NULL;
        fDifferCount = 0;
    }

    // Copy over the new differs
    fDifferCount = differs.count();
    fDiffers = SkNEW_ARRAY(SkImageDiffer*, fDifferCount);
    differs.copy(fDiffers);
}

static SkString get_common_prefix(const SkString& a, const SkString& b) {
    const size_t maxPrefixLength = SkTMin(a.size(), b.size());
    SkASSERT(maxPrefixLength > 0);
    for (size_t x = 0; x < maxPrefixLength; ++x) {
        if (a[x] != b[x]) {
            SkString result;
            result.set(a.c_str(), x);
            return result;
        }
    }
    if (a.size() > b.size()) {
        return b;
    } else {
        return a;
    }
}

static SkString get_combined_name(const SkString& a, const SkString& b) {
    // Note (stephana): We must keep this function in sync with
    // getImageDiffRelativeUrl() in static/loader.js (under rebaseline_server).
    SkString result = a;
    result.append("-vs-");
    result.append(b);
    sk_tools::replace_char(&result, '.', '_');
    return result;
}

void SkDiffContext::addDiff(const char* baselinePath, const char* testPath) {
    // Load the images at the paths
    SkBitmap baselineBitmap;
    SkBitmap testBitmap;
    if (!SkImageDecoder::DecodeFile(baselinePath, &baselineBitmap)) {
        SkDebugf("Failed to load bitmap \"%s\"\n", baselinePath);
        return;
    }
    if (!SkImageDecoder::DecodeFile(testPath, &testBitmap)) {
        SkDebugf("Failed to load bitmap \"%s\"\n", testPath);
        return;
    }

    // Setup a record for this diff
    fRecordMutex.acquire();
    DiffRecord* newRecord = fRecords.addToHead(DiffRecord());
    fRecordMutex.release();

    // compute the common name
    SkString baseName = SkOSPath::Basename(baselinePath);
    SkString testName = SkOSPath::Basename(testPath);

    if (longNames) {
        newRecord->fCommonName = get_combined_name(baseName, testName);
    } else {
        newRecord->fCommonName = get_common_prefix(baseName, testName);
    }
    newRecord->fCommonName.append(".png");

    newRecord->fBaselinePath = baselinePath;
    newRecord->fTestPath = testPath;
    newRecord->fSize = SkISize::Make(baselineBitmap.width(), baselineBitmap.height());

    // only generate diff images if we have a place to store them
    SkImageDiffer::BitmapsToCreate bitmapsToCreate;
    bitmapsToCreate.alphaMask = !fAlphaMaskDir.isEmpty();
    bitmapsToCreate.rgbDiff = !fRgbDiffDir.isEmpty();
    bitmapsToCreate.whiteDiff = !fWhiteDiffDir.isEmpty();

    // Perform each diff
    for (int differIndex = 0; differIndex < fDifferCount; differIndex++) {
        SkImageDiffer* differ = fDiffers[differIndex];

        // Copy the results into data for this record
        DiffData& diffData = newRecord->fDiffs.push_back();
        diffData.fDiffName = differ->getName();

        if (!differ->diff(&baselineBitmap, &testBitmap, bitmapsToCreate, &diffData.fResult)) {
            // if the diff failed, record -1 as the result
            // TODO(djsollen): Record more detailed information about exactly what failed.
            // (Image dimension mismatch? etc.)  See http://skbug.com/2710 ('make skpdiff
            // report more detail when it fails to compare two images')
            diffData.fResult.result = -1;
            continue;
        }

        if (bitmapsToCreate.alphaMask
                && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
                && !diffData.fResult.poiAlphaMask.empty()
                && !newRecord->fCommonName.isEmpty()) {

            newRecord->fAlphaMaskPath = SkOSPath::Join(fAlphaMaskDir.c_str(),
                                                       newRecord->fCommonName.c_str());

            // compute the image diff and output it
            SkBitmap copy;
            diffData.fResult.poiAlphaMask.copyTo(&copy, kN32_SkColorType);
            SkImageEncoder::EncodeFile(newRecord->fAlphaMaskPath.c_str(), copy,
                                       SkImageEncoder::kPNG_Type, 100);

            // cleanup the existing bitmap to free up resources;
            diffData.fResult.poiAlphaMask.reset();

            bitmapsToCreate.alphaMask = false;
        }

        if (bitmapsToCreate.rgbDiff
                && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
                && !diffData.fResult.rgbDiffBitmap.empty()
                && !newRecord->fCommonName.isEmpty()) {
            // TODO(djsollen): Rather than taking the max r/g/b diffs that come back from
            // a particular differ and storing them as toplevel fields within
            // newRecord, we should extend outputRecords() to report optional
            // fields for each differ (not just "result" and "pointsOfInterest").
            // See http://skbug.com/2712 ('allow skpdiff to report different sets
            // of result fields for different comparison algorithms')
            newRecord->fMaxRedDiff = diffData.fResult.maxRedDiff;
            newRecord->fMaxGreenDiff = diffData.fResult.maxGreenDiff;
            newRecord->fMaxBlueDiff = diffData.fResult.maxBlueDiff;

            newRecord->fRgbDiffPath = SkOSPath::Join(fRgbDiffDir.c_str(),
                                                     newRecord->fCommonName.c_str());
            SkImageEncoder::EncodeFile(newRecord->fRgbDiffPath.c_str(),
                                       diffData.fResult.rgbDiffBitmap,
                                       SkImageEncoder::kPNG_Type, 100);
            diffData.fResult.rgbDiffBitmap.reset();
            bitmapsToCreate.rgbDiff = false;
        }

        if (bitmapsToCreate.whiteDiff
                && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
                && !diffData.fResult.whiteDiffBitmap.empty()
                && !newRecord->fCommonName.isEmpty()) {
            newRecord->fWhiteDiffPath = SkOSPath::Join(fWhiteDiffDir.c_str(),
                                                       newRecord->fCommonName.c_str());
            SkImageEncoder::EncodeFile(newRecord->fWhiteDiffPath.c_str(),
                                       diffData.fResult.whiteDiffBitmap,
                                       SkImageEncoder::kPNG_Type, 100);
            diffData.fResult.whiteDiffBitmap.reset();
            bitmapsToCreate.whiteDiff = false;
        }
    }
}

class SkThreadedDiff : public SkRunnable {
public:
    SkThreadedDiff() : fDiffContext(NULL) { }

    void setup(SkDiffContext* diffContext, const SkString& baselinePath, const SkString& testPath) {
        fDiffContext = diffContext;
        fBaselinePath = baselinePath;
        fTestPath = testPath;
    }

    virtual void run() SK_OVERRIDE {
        fDiffContext->addDiff(fBaselinePath.c_str(), fTestPath.c_str());
    }

private:
    SkDiffContext* fDiffContext;
    SkString fBaselinePath;
    SkString fTestPath;
};

void SkDiffContext::diffDirectories(const char baselinePath[], const char testPath[]) {
    // Get the files in the baseline, we will then look for those inside the test path
    SkTArray<SkString> baselineEntries;
    if (!get_directory(baselinePath, &baselineEntries)) {
        SkDebugf("Unable to open path \"%s\"\n", baselinePath);
        return;
    }

    SkTaskGroup tg;
    SkTArray<SkThreadedDiff> runnableDiffs;
    runnableDiffs.reset(baselineEntries.count());

    for (int x = 0; x < baselineEntries.count(); x++) {
        const char* baseFilename = baselineEntries[x].c_str();

        // Find the real location of each file to compare
        SkString baselineFile = SkOSPath::Join(baselinePath, baseFilename);
        SkString testFile = SkOSPath::Join(testPath, baseFilename);

        // Check that the test file exists and is a file
        if (sk_exists(testFile.c_str()) && !sk_isdir(testFile.c_str())) {
            // Queue up the comparison with the differ
            runnableDiffs[x].setup(this, baselineFile, testFile);
            tg.add(&runnableDiffs[x]);
        } else {
            SkDebugf("Baseline file \"%s\" has no corresponding test file\n", baselineFile.c_str());
        }
    }
}


void SkDiffContext::diffPatterns(const char baselinePattern[], const char testPattern[]) {
    // Get the files in the baseline and test patterns. Because they are in sorted order, it's easy
    // to find corresponding images by matching entry indices.

    SkTArray<SkString> baselineEntries;
    if (!glob_files(baselinePattern, &baselineEntries)) {
        SkDebugf("Unable to get pattern \"%s\"\n", baselinePattern);
        return;
    }

    SkTArray<SkString> testEntries;
    if (!glob_files(testPattern, &testEntries)) {
        SkDebugf("Unable to get pattern \"%s\"\n", testPattern);
        return;
    }

    if (baselineEntries.count() != testEntries.count()) {
        SkDebugf("Baseline and test patterns do not yield corresponding number of files\n");
        return;
    }

    SkTaskGroup tg;
    SkTArray<SkThreadedDiff> runnableDiffs;
    runnableDiffs.reset(baselineEntries.count());

    for (int x = 0; x < baselineEntries.count(); x++) {
        runnableDiffs[x].setup(this, baselineEntries[x], testEntries[x]);
        tg.add(&runnableDiffs[x]);
    }
}

void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) {
    SkTLList<DiffRecord>::Iter iter(fRecords, SkTLList<DiffRecord>::Iter::kHead_IterStart);
    DiffRecord* currentRecord = iter.get();

    if (useJSONP) {
        stream.writeText("var SkPDiffRecords = {\n");
    } else {
        stream.writeText("{\n");
    }

    // TODO(djsollen): Would it be better to use the jsoncpp library to write out the JSON?
    // This manual approach is probably more efficient, but it sure is ugly.
    // See http://skbug.com/2713 ('make skpdiff use jsoncpp library to write out
    // JSON output, instead of manual writeText() calls?')
    stream.writeText("    \"records\": [\n");
    while (NULL != currentRecord) {
        stream.writeText("        {\n");

            SkString baselineAbsPath = get_absolute_path(currentRecord->fBaselinePath);
            SkString testAbsPath = get_absolute_path(currentRecord->fTestPath);

            stream.writeText("            \"commonName\": \"");
            stream.writeText(currentRecord->fCommonName.c_str());
            stream.writeText("\",\n");

            stream.writeText("            \"differencePath\": \"");
            stream.writeText(get_absolute_path(currentRecord->fAlphaMaskPath).c_str());
            stream.writeText("\",\n");

            stream.writeText("            \"rgbDiffPath\": \"");
            stream.writeText(get_absolute_path(currentRecord->fRgbDiffPath).c_str());
            stream.writeText("\",\n");

            stream.writeText("            \"whiteDiffPath\": \"");
            stream.writeText(get_absolute_path(currentRecord->fWhiteDiffPath).c_str());
            stream.writeText("\",\n");

            stream.writeText("            \"baselinePath\": \"");
            stream.writeText(baselineAbsPath.c_str());
            stream.writeText("\",\n");

            stream.writeText("            \"testPath\": \"");
            stream.writeText(testAbsPath.c_str());
            stream.writeText("\",\n");

            stream.writeText("            \"width\": ");
            stream.writeDecAsText(currentRecord->fSize.width());
            stream.writeText(",\n");
            stream.writeText("            \"height\": ");
            stream.writeDecAsText(currentRecord->fSize.height());
            stream.writeText(",\n");

            stream.writeText("            \"maxRedDiff\": ");
            stream.writeDecAsText(currentRecord->fMaxRedDiff);
            stream.writeText(",\n");
            stream.writeText("            \"maxGreenDiff\": ");
            stream.writeDecAsText(currentRecord->fMaxGreenDiff);
            stream.writeText(",\n");
            stream.writeText("            \"maxBlueDiff\": ");
            stream.writeDecAsText(currentRecord->fMaxBlueDiff);
            stream.writeText(",\n");

            stream.writeText("            \"diffs\": [\n");
            for (int diffIndex = 0; diffIndex < currentRecord->fDiffs.count(); diffIndex++) {
                DiffData& data = currentRecord->fDiffs[diffIndex];
                stream.writeText("                {\n");

                    stream.writeText("                    \"differName\": \"");
                    stream.writeText(data.fDiffName);
                    stream.writeText("\",\n");

                    stream.writeText("                    \"result\": ");
                    stream.writeScalarAsText((SkScalar)data.fResult.result);
                    stream.writeText(",\n");

                    stream.writeText("                    \"pointsOfInterest\": ");
                    stream.writeDecAsText(data.fResult.poiCount);
                    stream.writeText("\n");

                stream.writeText("                }");

                // JSON does not allow trailing commas
                if (diffIndex + 1 < currentRecord->fDiffs.count()) {
                    stream.writeText(",");
                }
                stream.writeText("                \n");
            }
            stream.writeText("            ]\n");

        stream.writeText("        }");

        currentRecord = iter.next();

        // JSON does not allow trailing commas
        if (NULL != currentRecord) {
            stream.writeText(",");
        }
        stream.writeText("\n");
    }
    stream.writeText("    ]\n");
    if (useJSONP) {
        stream.writeText("};\n");
    } else {
        stream.writeText("}\n");
    }
}

void SkDiffContext::outputCsv(SkWStream& stream) {
    SkTDict<int> columns(2);
    int cntColumns = 0;

    stream.writeText("key");

    SkTLList<DiffRecord>::Iter iter(fRecords, SkTLList<DiffRecord>::Iter::kHead_IterStart);
    DiffRecord* currentRecord = iter.get();

    // Write CSV header and create a dictionary of all columns.
    while (NULL != currentRecord) {
        for (int diffIndex = 0; diffIndex < currentRecord->fDiffs.count(); diffIndex++) {
            DiffData& data = currentRecord->fDiffs[diffIndex];
            if (!columns.find(data.fDiffName)) {
                columns.set(data.fDiffName, cntColumns);
                stream.writeText(", ");
                stream.writeText(data.fDiffName);
                cntColumns++;
            }
        }
        currentRecord = iter.next();
    }
    stream.writeText("\n");

    double values[100];
    SkASSERT(cntColumns < 100);  // Make the array larger, if we ever have so many diff types.

    SkTLList<DiffRecord>::Iter iter2(fRecords, SkTLList<DiffRecord>::Iter::kHead_IterStart);
    currentRecord = iter2.get();
    while (NULL != currentRecord) {
        for (int i = 0; i < cntColumns; i++) {
            values[i] = -1;
        }

        for (int diffIndex = 0; diffIndex < currentRecord->fDiffs.count(); diffIndex++) {
            DiffData& data = currentRecord->fDiffs[diffIndex];
            int index = -1;
            SkAssertResult(columns.find(data.fDiffName, &index));
            SkASSERT(index >= 0 && index < cntColumns);
            values[index] = data.fResult.result;
        }

        const char* filename = currentRecord->fBaselinePath.c_str() +
                strlen(currentRecord->fBaselinePath.c_str()) - 1;
        while (filename > currentRecord->fBaselinePath.c_str() && *(filename - 1) != '/') {
            filename--;
        }

        stream.writeText(filename);

        for (int i = 0; i < cntColumns; i++) {
            SkString str;
            str.printf(", %f", values[i]);
            stream.writeText(str.c_str());
        }
        stream.writeText("\n");

        currentRecord = iter2.next();
    }
}
