/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "skdiff.h"
#include "skdiff_html.h"
#include "skdiff_utils.h"
#include "SkBitmap.h"
#include "SkData.h"
#include "SkForceLinking.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkOSFile.h"
#include "SkStream.h"
#include "SkTDArray.h"
#include "../private/SkTSearch.h"

#include <stdlib.h>

__SK_FORCE_IMAGE_DECODER_LINKING;

/**
 * skdiff
 *
 * Given three directory names, expects to find identically-named files in
 * each of the first two; the first are treated as a set of baseline,
 * the second a set of variant images, and a diff image is written into the
 * third directory for each pair.
 * Creates an index.html in the current third directory to compare each
 * pair that does not match exactly.
 * Recursively descends directories, unless run with --norecurse.
 *
 * Returns zero exit code if all images match across baseDir and comparisonDir.
 */

typedef SkTDArray<SkString*> StringArray;
typedef StringArray FileArray;

static void add_unique_basename(StringArray* array, const SkString& filename) {
    // trim off dirs
    const char* src = filename.c_str();
    const char* trimmed = strrchr(src, SkPATH_SEPARATOR);
    if (trimmed) {
        trimmed += 1;   // skip the separator
    } else {
        trimmed = src;
    }
    const char* end = strrchr(trimmed, '.');
    if (!end) {
        end = trimmed + strlen(trimmed);
    }
    SkString result(trimmed, end - trimmed);

    // only add unique entries
    for (int i = 0; i < array->count(); ++i) {
        if (*array->getAt(i) == result) {
            return;
        }
    }
    *array->append() = new SkString(result);
}

struct DiffSummary {
    DiffSummary ()
        : fNumMatches(0)
        , fNumMismatches(0)
        , fMaxMismatchV(0)
        , fMaxMismatchPercent(0) { };

    ~DiffSummary() {
        for (int i = 0; i < DiffRecord::kResultCount; ++i) {
            fResultsOfType[i].deleteAll();
        }
        for (int base = 0; base < DiffResource::kStatusCount; ++base) {
            for (int comparison = 0; comparison < DiffResource::kStatusCount; ++comparison) {
                fStatusOfType[base][comparison].deleteAll();
            }
        }
    }

    uint32_t fNumMatches;
    uint32_t fNumMismatches;
    uint32_t fMaxMismatchV;
    float fMaxMismatchPercent;

    FileArray fResultsOfType[DiffRecord::kResultCount];
    FileArray fStatusOfType[DiffResource::kStatusCount][DiffResource::kStatusCount];

    StringArray fFailedBaseNames[DiffRecord::kResultCount];

    void printContents(const FileArray& fileArray,
                       const char* baseStatus, const char* comparisonStatus,
                       bool listFilenames) {
        int n = fileArray.count();
        printf("%d file pairs %s in baseDir and %s in comparisonDir",
                n,            baseStatus,       comparisonStatus);
        if (listFilenames) {
            printf(": ");
            for (int i = 0; i < n; ++i) {
                printf("%s ", fileArray[i]->c_str());
            }
        }
        printf("\n");
    }

    void printStatus(bool listFilenames,
                     bool failOnStatusType[DiffResource::kStatusCount]
                                          [DiffResource::kStatusCount]) {
        typedef DiffResource::Status Status;

        for (int base = 0; base < DiffResource::kStatusCount; ++base) {
            Status baseStatus = static_cast<Status>(base);
            for (int comparison = 0; comparison < DiffResource::kStatusCount; ++comparison) {
                Status comparisonStatus = static_cast<Status>(comparison);
                const FileArray& fileArray = fStatusOfType[base][comparison];
                if (fileArray.count() > 0) {
                    if (failOnStatusType[base][comparison]) {
                        printf("   [*] ");
                    } else {
                        printf("   [_] ");
                    }
                    printContents(fileArray,
                                  DiffResource::getStatusDescription(baseStatus),
                                  DiffResource::getStatusDescription(comparisonStatus),
                                  listFilenames);
                }
            }
        }
    }

    // Print a line about the contents of this FileArray to stdout.
    void printContents(const FileArray& fileArray, const char* headerText, bool listFilenames) {
        int n = fileArray.count();
        printf("%d file pairs %s", n, headerText);
        if (listFilenames) {
            printf(": ");
            for (int i = 0; i < n; ++i) {
                printf("%s ", fileArray[i]->c_str());
            }
        }
        printf("\n");
    }

    void print(bool listFilenames, bool failOnResultType[DiffRecord::kResultCount],
               bool failOnStatusType[DiffResource::kStatusCount]
                                    [DiffResource::kStatusCount]) {
        printf("\ncompared %d file pairs:\n", fNumMatches + fNumMismatches);
        for (int resultInt = 0; resultInt < DiffRecord::kResultCount; ++resultInt) {
            DiffRecord::Result result = static_cast<DiffRecord::Result>(resultInt);
            if (failOnResultType[result]) {
                printf("[*] ");
            } else {
                printf("[_] ");
            }
            printContents(fResultsOfType[result], DiffRecord::getResultDescription(result),
                          listFilenames);
            if (DiffRecord::kCouldNotCompare_Result == result) {
                printStatus(listFilenames, failOnStatusType);
            }
        }
        printf("(results marked with [*] will cause nonzero return value)\n");
        printf("\nnumber of mismatching file pairs: %d\n", fNumMismatches);
        if (fNumMismatches > 0) {
            printf("Maximum pixel intensity mismatch %d\n", fMaxMismatchV);
            printf("Largest area mismatch was %.2f%% of pixels\n",fMaxMismatchPercent);
        }
    }

    void printfFailingBaseNames(const char separator[]) {
        for (int resultInt = 0; resultInt < DiffRecord::kResultCount; ++resultInt) {
            const StringArray& array = fFailedBaseNames[resultInt];
            if (array.count()) {
                printf("%s [%d]%s", DiffRecord::ResultNames[resultInt], array.count(), separator);
                for (int j = 0; j < array.count(); ++j) {
                    printf("%s%s", array[j]->c_str(), separator);
                }
                printf("\n");
            }
        }
    }

    void add (DiffRecord* drp) {
        uint32_t mismatchValue;

        if (drp->fBase.fFilename.equals(drp->fComparison.fFilename)) {
            fResultsOfType[drp->fResult].push(new SkString(drp->fBase.fFilename));
        } else {
            SkString* blame = new SkString("(");
            blame->append(drp->fBase.fFilename);
            blame->append(", ");
            blame->append(drp->fComparison.fFilename);
            blame->append(")");
            fResultsOfType[drp->fResult].push(blame);
        }
        switch (drp->fResult) {
          case DiffRecord::kEqualBits_Result:
            fNumMatches++;
            break;
          case DiffRecord::kEqualPixels_Result:
            fNumMatches++;
            break;
          case DiffRecord::kDifferentSizes_Result:
            fNumMismatches++;
            break;
          case DiffRecord::kDifferentPixels_Result:
            fNumMismatches++;
            if (drp->fFractionDifference * 100 > fMaxMismatchPercent) {
                fMaxMismatchPercent = drp->fFractionDifference * 100;
            }
            mismatchValue = MAX3(drp->fMaxMismatchR, drp->fMaxMismatchG,
                                 drp->fMaxMismatchB);
            if (mismatchValue > fMaxMismatchV) {
                fMaxMismatchV = mismatchValue;
            }
            break;
          case DiffRecord::kCouldNotCompare_Result:
            fNumMismatches++;
            fStatusOfType[drp->fBase.fStatus][drp->fComparison.fStatus].push(
                    new SkString(drp->fBase.fFilename));
            break;
          case DiffRecord::kUnknown_Result:
            SkDEBUGFAIL("adding uncategorized DiffRecord");
            break;
          default:
            SkDEBUGFAIL("adding DiffRecord with unhandled fResult value");
            break;
        }

        switch (drp->fResult) {
            case DiffRecord::kEqualBits_Result:
            case DiffRecord::kEqualPixels_Result:
                break;
            default:
                add_unique_basename(&fFailedBaseNames[drp->fResult], drp->fBase.fFilename);
                break;
        }
    }
};

/// Returns true if string contains any of these substrings.
static bool string_contains_any_of(const SkString& string,
                                   const StringArray& substrings) {
    for (int i = 0; i < substrings.count(); i++) {
        if (string.contains(substrings[i]->c_str())) {
            return true;
        }
    }
    return false;
}

/// Internal (potentially recursive) implementation of get_file_list.
static void get_file_list_subdir(const SkString& rootDir, const SkString& subDir,
                                 const StringArray& matchSubstrings,
                                 const StringArray& nomatchSubstrings,
                                 bool recurseIntoSubdirs, FileArray *files) {
    bool isSubDirEmpty = subDir.isEmpty();
    SkString dir(rootDir);
    if (!isSubDirEmpty) {
        dir.append(PATH_DIV_STR);
        dir.append(subDir);
    }

    // Iterate over files (not directories) within dir.
    SkOSFile::Iter fileIterator(dir.c_str());
    SkString fileName;
    while (fileIterator.next(&fileName, false)) {
        if (fileName.startsWith(".")) {
            continue;
        }
        SkString pathRelativeToRootDir(subDir);
        if (!isSubDirEmpty) {
            pathRelativeToRootDir.append(PATH_DIV_STR);
        }
        pathRelativeToRootDir.append(fileName);
        if (string_contains_any_of(pathRelativeToRootDir, matchSubstrings) &&
            !string_contains_any_of(pathRelativeToRootDir, nomatchSubstrings)) {
            files->push(new SkString(pathRelativeToRootDir));
        }
    }

    // Recurse into any non-ignored subdirectories.
    if (recurseIntoSubdirs) {
        SkOSFile::Iter dirIterator(dir.c_str());
        SkString dirName;
        while (dirIterator.next(&dirName, true)) {
            if (dirName.startsWith(".")) {
                continue;
            }
            SkString pathRelativeToRootDir(subDir);
            if (!isSubDirEmpty) {
                pathRelativeToRootDir.append(PATH_DIV_STR);
            }
            pathRelativeToRootDir.append(dirName);
            if (!string_contains_any_of(pathRelativeToRootDir, nomatchSubstrings)) {
                get_file_list_subdir(rootDir, pathRelativeToRootDir,
                                     matchSubstrings, nomatchSubstrings, recurseIntoSubdirs,
                                     files);
            }
        }
    }
}

/// Iterate over dir and get all files whose filename:
///  - matches any of the substrings in matchSubstrings, but...
///  - DOES NOT match any of the substrings in nomatchSubstrings
///  - DOES NOT start with a dot (.)
/// Adds the matching files to the list in *files.
static void get_file_list(const SkString& dir,
                          const StringArray& matchSubstrings,
                          const StringArray& nomatchSubstrings,
                          bool recurseIntoSubdirs, FileArray *files) {
    get_file_list_subdir(dir, SkString(""),
                         matchSubstrings, nomatchSubstrings, recurseIntoSubdirs,
                         files);
}

static void release_file_list(FileArray *files) {
    files->deleteAll();
}

/// Comparison routines for qsort, sort by file names.
static int compare_file_name_metrics(SkString **lhs, SkString **rhs) {
    return strcmp((*lhs)->c_str(), (*rhs)->c_str());
}

class AutoReleasePixels {
public:
    AutoReleasePixels(DiffRecord* drp)
    : fDrp(drp) {
        SkASSERT(drp != nullptr);
    }
    ~AutoReleasePixels() {
        fDrp->fBase.fBitmap.setPixelRef(nullptr);
        fDrp->fComparison.fBitmap.setPixelRef(nullptr);
        fDrp->fDifference.fBitmap.setPixelRef(nullptr);
        fDrp->fWhite.fBitmap.setPixelRef(nullptr);
    }

private:
    DiffRecord* fDrp;
};

static void get_bounds(DiffResource& resource, const char* name) {
    if (resource.fBitmap.empty() && !DiffResource::isStatusFailed(resource.fStatus)) {
        SkAutoDataUnref fileBits(read_file(resource.fFullPath.c_str()));
        if (nullptr == fileBits) {
            SkDebugf("WARNING: couldn't read %s file <%s>\n", name, resource.fFullPath.c_str());
            resource.fStatus = DiffResource::kCouldNotRead_Status;
        } else {
            get_bitmap(fileBits, resource, SkImageDecoder::kDecodeBounds_Mode);
        }
    }
}

static void get_bounds(DiffRecord& drp) {
    get_bounds(drp.fBase, "base");
    get_bounds(drp.fComparison, "comparison");
}

#ifdef SK_OS_WIN
#define ANSI_COLOR_RED     ""
#define ANSI_COLOR_GREEN   ""
#define ANSI_COLOR_YELLOW  ""
#define ANSI_COLOR_RESET   ""
#else
#define ANSI_COLOR_RED     "\x1b[31m"
#define ANSI_COLOR_GREEN   "\x1b[32m"
#define ANSI_COLOR_YELLOW  "\x1b[33m"
#define ANSI_COLOR_RESET   "\x1b[0m"
#endif

#define VERBOSE_STATUS(status,color,filename) if (verbose) printf( "[ " color " %10s " ANSI_COLOR_RESET " ] %s\n", status, filename->c_str())

/// Creates difference images, returns the number that have a 0 metric.
/// If outputDir.isEmpty(), don't write out diff files.
static void create_diff_images (DiffMetricProc dmp,
                                const int colorThreshold,
                                RecordArray* differences,
                                const SkString& baseDir,
                                const SkString& comparisonDir,
                                const SkString& outputDir,
                                const StringArray& matchSubstrings,
                                const StringArray& nomatchSubstrings,
                                bool recurseIntoSubdirs,
                                bool getBounds,
                                bool verbose,
                                DiffSummary* summary) {
    SkASSERT(!baseDir.isEmpty());
    SkASSERT(!comparisonDir.isEmpty());

    FileArray baseFiles;
    FileArray comparisonFiles;

    get_file_list(baseDir, matchSubstrings, nomatchSubstrings, recurseIntoSubdirs, &baseFiles);
    get_file_list(comparisonDir, matchSubstrings, nomatchSubstrings, recurseIntoSubdirs,
                  &comparisonFiles);

    if (!baseFiles.isEmpty()) {
        qsort(baseFiles.begin(), baseFiles.count(), sizeof(SkString*),
              SkCastForQSort(compare_file_name_metrics));
    }
    if (!comparisonFiles.isEmpty()) {
        qsort(comparisonFiles.begin(), comparisonFiles.count(),
              sizeof(SkString*), SkCastForQSort(compare_file_name_metrics));
    }

    int i = 0;
    int j = 0;

    while (i < baseFiles.count() &&
           j < comparisonFiles.count()) {

        SkString basePath(baseDir);
        SkString comparisonPath(comparisonDir);

        DiffRecord *drp = new DiffRecord;
        int v = strcmp(baseFiles[i]->c_str(), comparisonFiles[j]->c_str());

        if (v < 0) {
            // in baseDir, but not in comparisonDir
            drp->fResult = DiffRecord::kCouldNotCompare_Result;

            basePath.append(*baseFiles[i]);
            comparisonPath.append(*baseFiles[i]);

            drp->fBase.fFilename = *baseFiles[i];
            drp->fBase.fFullPath = basePath;
            drp->fBase.fStatus = DiffResource::kExists_Status;

            drp->fComparison.fFilename = *baseFiles[i];
            drp->fComparison.fFullPath = comparisonPath;
            drp->fComparison.fStatus = DiffResource::kDoesNotExist_Status;

            VERBOSE_STATUS("MISSING", ANSI_COLOR_YELLOW, baseFiles[i]);

            ++i;
        } else if (v > 0) {
            // in comparisonDir, but not in baseDir
            drp->fResult = DiffRecord::kCouldNotCompare_Result;

            basePath.append(*comparisonFiles[j]);
            comparisonPath.append(*comparisonFiles[j]);

            drp->fBase.fFilename = *comparisonFiles[j];
            drp->fBase.fFullPath = basePath;
            drp->fBase.fStatus = DiffResource::kDoesNotExist_Status;

            drp->fComparison.fFilename = *comparisonFiles[j];
            drp->fComparison.fFullPath = comparisonPath;
            drp->fComparison.fStatus = DiffResource::kExists_Status;

            VERBOSE_STATUS("MISSING", ANSI_COLOR_YELLOW, comparisonFiles[j]);

            ++j;
        } else {
            // Found the same filename in both baseDir and comparisonDir.
            SkASSERT(DiffRecord::kUnknown_Result == drp->fResult);

            basePath.append(*baseFiles[i]);
            comparisonPath.append(*comparisonFiles[j]);

            drp->fBase.fFilename = *baseFiles[i];
            drp->fBase.fFullPath = basePath;
            drp->fBase.fStatus = DiffResource::kExists_Status;

            drp->fComparison.fFilename = *comparisonFiles[j];
            drp->fComparison.fFullPath = comparisonPath;
            drp->fComparison.fStatus = DiffResource::kExists_Status;

            SkAutoDataUnref baseFileBits(read_file(drp->fBase.fFullPath.c_str()));
            if (baseFileBits) {
                drp->fBase.fStatus = DiffResource::kRead_Status;
            }
            SkAutoDataUnref comparisonFileBits(read_file(drp->fComparison.fFullPath.c_str()));
            if (comparisonFileBits) {
                drp->fComparison.fStatus = DiffResource::kRead_Status;
            }
            if (nullptr == baseFileBits || nullptr == comparisonFileBits) {
                if (nullptr == baseFileBits) {
                    drp->fBase.fStatus = DiffResource::kCouldNotRead_Status;
                    VERBOSE_STATUS("READ FAIL", ANSI_COLOR_RED, baseFiles[i]);
                }
                if (nullptr == comparisonFileBits) {
                    drp->fComparison.fStatus = DiffResource::kCouldNotRead_Status;
                    VERBOSE_STATUS("READ FAIL", ANSI_COLOR_RED, comparisonFiles[j]);
                }
                drp->fResult = DiffRecord::kCouldNotCompare_Result;

            } else if (are_buffers_equal(baseFileBits, comparisonFileBits)) {
                drp->fResult = DiffRecord::kEqualBits_Result;
                VERBOSE_STATUS("MATCH", ANSI_COLOR_GREEN, baseFiles[i]);
            } else {
                AutoReleasePixels arp(drp);
                get_bitmap(baseFileBits, drp->fBase, SkImageDecoder::kDecodePixels_Mode);
                get_bitmap(comparisonFileBits, drp->fComparison,
                           SkImageDecoder::kDecodePixels_Mode);
                VERBOSE_STATUS("DIFFERENT", ANSI_COLOR_RED, baseFiles[i]);
                if (DiffResource::kDecoded_Status == drp->fBase.fStatus &&
                    DiffResource::kDecoded_Status == drp->fComparison.fStatus) {
                    create_and_write_diff_image(drp, dmp, colorThreshold,
                                                outputDir, drp->fBase.fFilename);
                } else {
                    drp->fResult = DiffRecord::kCouldNotCompare_Result;
                }
            }

            ++i;
            ++j;
        }

        if (getBounds) {
            get_bounds(*drp);
        }
        SkASSERT(DiffRecord::kUnknown_Result != drp->fResult);
        differences->push(drp);
        summary->add(drp);
    }

    for (; i < baseFiles.count(); ++i) {
        // files only in baseDir
        DiffRecord *drp = new DiffRecord();
        drp->fBase.fFilename = *baseFiles[i];
        drp->fBase.fFullPath = baseDir;
        drp->fBase.fFullPath.append(drp->fBase.fFilename);
        drp->fBase.fStatus = DiffResource::kExists_Status;

        drp->fComparison.fFilename = *baseFiles[i];
        drp->fComparison.fFullPath = comparisonDir;
        drp->fComparison.fFullPath.append(drp->fComparison.fFilename);
        drp->fComparison.fStatus = DiffResource::kDoesNotExist_Status;

        drp->fResult = DiffRecord::kCouldNotCompare_Result;
        if (getBounds) {
            get_bounds(*drp);
        }
        differences->push(drp);
        summary->add(drp);
    }

    for (; j < comparisonFiles.count(); ++j) {
        // files only in comparisonDir
        DiffRecord *drp = new DiffRecord();
        drp->fBase.fFilename = *comparisonFiles[j];
        drp->fBase.fFullPath = baseDir;
        drp->fBase.fFullPath.append(drp->fBase.fFilename);
        drp->fBase.fStatus = DiffResource::kDoesNotExist_Status;

        drp->fComparison.fFilename = *comparisonFiles[j];
        drp->fComparison.fFullPath = comparisonDir;
        drp->fComparison.fFullPath.append(drp->fComparison.fFilename);
        drp->fComparison.fStatus = DiffResource::kExists_Status;

        drp->fResult = DiffRecord::kCouldNotCompare_Result;
        if (getBounds) {
            get_bounds(*drp);
        }
        differences->push(drp);
        summary->add(drp);
    }

    release_file_list(&baseFiles);
    release_file_list(&comparisonFiles);
}

static void usage (char * argv0) {
    SkDebugf("Skia baseline image diff tool\n");
    SkDebugf("\n"
"Usage: \n"
"    %s <baseDir> <comparisonDir> [outputDir] \n", argv0);
    SkDebugf(
"\nArguments:"
"\n    --failonresult <result>: After comparing all file pairs, exit with nonzero"
"\n                             return code (number of file pairs yielding this"
"\n                             result) if any file pairs yielded this result."
"\n                             This flag may be repeated, in which case the"
"\n                             return code will be the number of fail pairs"
"\n                             yielding ANY of these results."
"\n    --failonstatus <baseStatus> <comparisonStatus>: exit with nonzero return"
"\n                             code if any file pairs yielded this status."
"\n    --help: display this info"
"\n    --listfilenames: list all filenames for each result type in stdout"
"\n    --match <substring>: compare files whose filenames contain this substring;"
"\n                         if unspecified, compare ALL files."
"\n                         this flag may be repeated."
"\n    --nodiffs: don't write out image diffs or index.html, just generate"
"\n               report on stdout"
"\n    --nomatch <substring>: regardless of --match, DO NOT compare files whose"
"\n                           filenames contain this substring."
"\n                           this flag may be repeated."
"\n    --noprintdirs: do not print the directories used."
"\n    --norecurse: do not recurse into subdirectories."
"\n    --sortbymaxmismatch: sort by worst color channel mismatch;"
"\n                         break ties with -sortbymismatch"
"\n    --sortbymismatch: sort by average color channel mismatch"
"\n    --threshold <n>: only report differences > n (per color channel) [default 0]"
"\n    --weighted: sort by # pixels different weighted by color difference"
"\n"
"\n    baseDir: directory to read baseline images from."
"\n    comparisonDir: directory to read comparison images from"
"\n    outputDir: directory to write difference images and index.html to;"
"\n               defaults to comparisonDir"
"\n"
"\nIf no sort is specified, it will sort by fraction of pixels mismatching."
"\n");
}

const int kNoError = 0;
const int kGenericError = -1;

int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
    DiffMetricProc diffProc = compute_diff_pmcolor;
    int (*sortProc)(const void*, const void*) = compare<CompareDiffMetrics>;

    // Maximum error tolerated in any one color channel in any one pixel before
    // a difference is reported.
    int colorThreshold = 0;
    SkString baseDir;
    SkString comparisonDir;
    SkString outputDir;

    StringArray matchSubstrings;
    StringArray nomatchSubstrings;

    bool generateDiffs = true;
    bool listFilenames = false;
    bool printDirNames = true;
    bool recurseIntoSubdirs = true;
    bool verbose = false;
    bool listFailingBase = false;

    RecordArray differences;
    DiffSummary summary;

    bool failOnResultType[DiffRecord::kResultCount];
    for (int i = 0; i < DiffRecord::kResultCount; i++) {
        failOnResultType[i] = false;
    }

    bool failOnStatusType[DiffResource::kStatusCount][DiffResource::kStatusCount];
    for (int base = 0; base < DiffResource::kStatusCount; ++base) {
        for (int comparison = 0; comparison < DiffResource::kStatusCount; ++comparison) {
            failOnStatusType[base][comparison] = false;
        }
    }

    int i;
    int numUnflaggedArguments = 0;
    for (i = 1; i < argc; i++) {
        if (!strcmp(argv[i], "--failonresult")) {
            if (argc == ++i) {
                SkDebugf("failonresult expects one argument.\n");
                continue;
            }
            DiffRecord::Result type = DiffRecord::getResultByName(argv[i]);
            if (type != DiffRecord::kResultCount) {
                failOnResultType[type] = true;
            } else {
                SkDebugf("ignoring unrecognized result <%s>\n", argv[i]);
            }
            continue;
        }
        if (!strcmp(argv[i], "--failonstatus")) {
            if (argc == ++i) {
                SkDebugf("failonstatus missing base status.\n");
                continue;
            }
            bool baseStatuses[DiffResource::kStatusCount];
            if (!DiffResource::getMatchingStatuses(argv[i], baseStatuses)) {
                SkDebugf("unrecognized base status <%s>\n", argv[i]);
            }

            if (argc == ++i) {
                SkDebugf("failonstatus missing comparison status.\n");
                continue;
            }
            bool comparisonStatuses[DiffResource::kStatusCount];
            if (!DiffResource::getMatchingStatuses(argv[i], comparisonStatuses)) {
                SkDebugf("unrecognized comarison status <%s>\n", argv[i]);
            }

            for (int base = 0; base < DiffResource::kStatusCount; ++base) {
                for (int comparison = 0; comparison < DiffResource::kStatusCount; ++comparison) {
                    failOnStatusType[base][comparison] |=
                        baseStatuses[base] && comparisonStatuses[comparison];
                }
            }
            continue;
        }
        if (!strcmp(argv[i], "--help")) {
            usage(argv[0]);
            return kNoError;
        }
        if (!strcmp(argv[i], "--listfilenames")) {
            listFilenames = true;
            continue;
        }
        if (!strcmp(argv[i], "--verbose")) {
            verbose = true;
            continue;
        }
        if (!strcmp(argv[i], "--match")) {
            matchSubstrings.push(new SkString(argv[++i]));
            continue;
        }
        if (!strcmp(argv[i], "--nodiffs")) {
            generateDiffs = false;
            continue;
        }
        if (!strcmp(argv[i], "--nomatch")) {
            nomatchSubstrings.push(new SkString(argv[++i]));
            continue;
        }
        if (!strcmp(argv[i], "--noprintdirs")) {
            printDirNames = false;
            continue;
        }
        if (!strcmp(argv[i], "--norecurse")) {
            recurseIntoSubdirs = false;
            continue;
        }
        if (!strcmp(argv[i], "--sortbymaxmismatch")) {
            sortProc = compare<CompareDiffMaxMismatches>;
            continue;
        }
        if (!strcmp(argv[i], "--sortbymismatch")) {
            sortProc = compare<CompareDiffMeanMismatches>;
            continue;
        }
        if (!strcmp(argv[i], "--threshold")) {
            colorThreshold = atoi(argv[++i]);
            continue;
        }
        if (!strcmp(argv[i], "--weighted")) {
            sortProc = compare<CompareDiffWeighted>;
            continue;
        }
        if (argv[i][0] != '-') {
            switch (numUnflaggedArguments++) {
                case 0:
                    baseDir.set(argv[i]);
                    continue;
                case 1:
                    comparisonDir.set(argv[i]);
                    continue;
                case 2:
                    outputDir.set(argv[i]);
                    continue;
                default:
                    SkDebugf("extra unflagged argument <%s>\n", argv[i]);
                    usage(argv[0]);
                    return kGenericError;
            }
        }
        if (!strcmp(argv[i], "--listFailingBase")) {
            listFailingBase = true;
            continue;
        }

        SkDebugf("Unrecognized argument <%s>\n", argv[i]);
        usage(argv[0]);
        return kGenericError;
    }

    if (numUnflaggedArguments == 2) {
        outputDir = comparisonDir;
    } else if (numUnflaggedArguments != 3) {
        usage(argv[0]);
        return kGenericError;
    }

    if (!baseDir.endsWith(PATH_DIV_STR)) {
        baseDir.append(PATH_DIV_STR);
    }
    if (printDirNames) {
        printf("baseDir is [%s]\n", baseDir.c_str());
    }

    if (!comparisonDir.endsWith(PATH_DIV_STR)) {
        comparisonDir.append(PATH_DIV_STR);
    }
    if (printDirNames) {
        printf("comparisonDir is [%s]\n", comparisonDir.c_str());
    }

    if (!outputDir.endsWith(PATH_DIV_STR)) {
        outputDir.append(PATH_DIV_STR);
    }
    if (generateDiffs) {
        if (printDirNames) {
            printf("writing diffs to outputDir is [%s]\n", outputDir.c_str());
        }
    } else {
        if (printDirNames) {
            printf("not writing any diffs to outputDir [%s]\n", outputDir.c_str());
        }
        outputDir.set("");
    }

    // If no matchSubstrings were specified, match ALL strings
    // (except for whatever nomatchSubstrings were specified, if any).
    if (matchSubstrings.isEmpty()) {
        matchSubstrings.push(new SkString(""));
    }

    create_diff_images(diffProc, colorThreshold, &differences,
                       baseDir, comparisonDir, outputDir,
                       matchSubstrings, nomatchSubstrings, recurseIntoSubdirs, generateDiffs,
                       verbose, &summary);
    summary.print(listFilenames, failOnResultType, failOnStatusType);

    if (listFailingBase) {
        summary.printfFailingBaseNames("\n");
    }

    if (differences.count()) {
        qsort(differences.begin(), differences.count(),
              sizeof(DiffRecord*), sortProc);
    }

    if (generateDiffs) {
        print_diff_page(summary.fNumMatches, colorThreshold, differences,
                        baseDir, comparisonDir, outputDir);
    }

    for (i = 0; i < differences.count(); i++) {
        delete differences[i];
    }
    matchSubstrings.deleteAll();
    nomatchSubstrings.deleteAll();

    int num_failing_results = 0;
    for (int i = 0; i < DiffRecord::kResultCount; i++) {
        if (failOnResultType[i]) {
            num_failing_results += summary.fResultsOfType[i].count();
        }
    }
    if (!failOnResultType[DiffRecord::kCouldNotCompare_Result]) {
        for (int base = 0; base < DiffResource::kStatusCount; ++base) {
            for (int comparison = 0; comparison < DiffResource::kStatusCount; ++comparison) {
                if (failOnStatusType[base][comparison]) {
                    num_failing_results += summary.fStatusOfType[base][comparison].count();
                }
            }
        }
    }

    // On Linux (and maybe other platforms too), any results outside of the
    // range [0...255] are wrapped (mod 256).  Do the conversion ourselves, to
    // make sure that we only return 0 when there were no failures.
    return (num_failing_results > 255) ? 255 : num_failing_results;
}

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