/*
 * 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 "SkImageEncoder.h"
#include "SkOSFile.h"
#include "SkStream.h"
#include "../private/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, true);
        }
    }
}

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));
    }

    if (!outputDir.isEmpty()) {
        sk_mkdir(outputDir.c_str());
    }

    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, false);
                get_bitmap(comparisonFileBits, drp->fComparison, false);
                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
