/*
 * 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 "CrashHandler.h"
// #include "OverwriteLine.h"
#include "Resources.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkColor.h"
#include "SkColorPriv.h"
#include "SkCommandLineFlags.h"
#include "SkForceLinking.h"
#include "SkGraphics.h"
#include "SkImageEncoder.h"
#include "SkOSFile.h"
#include "SkPathOpsDebug.h"
#include "SkPicture.h"
#include "SkRTConf.h"
#include "SkTSort.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkTArray.h"
#include "SkTDArray.h"
#include "SkTaskGroup.h"
#include "SkTemplates.h"
#include "SkTime.h"

#include <stdlib.h>

/* add local exceptions here */
/* TODO : add command flag interface */
const struct SkipOverTest {
    int directory;
    const char* filename;
    bool blamePathOps;
} skipOver[] = {
    { 2, "http___www_groupon_sg_.skp", false},  // SkAAClip::Builder::addRun SkASSERT(fBounds.contains(x, y));
    { 6, "http___www_googleventures_com_.skp", true},  // addTCoincident SkASSERT(test->fT < 1);
    { 7, "http___www_foxsports_nl_.skp", true},  // (no repro on mac) addT SkASSERT(this != other || fVerb == SkPath::kCubic_Verb)
    {13, "http___www_modernqigong_com_.skp", false},  // SkAAClip::Builder::addRun SkASSERT(fBounds.contains(x, y));
    {14, "http___www_devbridge_com_.skp", true},  // checkSmallCoincidence SkASSERT(!next->fSmall || checkMultiple);
    {16, "http___www_1023world_net_.skp", false},  // bitmap decode assert (corrupt skp?)
    {19, "http___www_alamdi_com_.skp", true},  // cubic/quad intersection
    {26, "http___www_liveencounters_net_.skp", true},  // (no repro on mac) checkSmall addT:549 (line, expects cubic)
    {28, "http___www_encros_fr_.skp", false},  // SkAAClip::Builder::addRun SkASSERT(fBounds.contains(x, y));
    {37, "http___www_familysurvivalprotocol_wordpress_com_.skp", true},  // bumpSpan SkASSERT(span->fOppValue >= 0);
    {39, "http___sufeinet_com_.skp", false}, // bitmap decode assert (corrupt skp?)
    {41, "http___www_rano360_com_.skp", true}, // checkSmallCoincidence SkASSERT(!next->fSmall || checkMultiple);
    {44, "http___www_firstunitedbank_com_.skp", true},  // addTCancel SkASSERT(oIndex > 0);
    {46, "http___www_shinydemos_com_.skp", true},  // addSimpleAngle SkASSERT(index == count() - 2);
    {48, "http___www_familysurvivalprotocol_com_.skp", true},  // bumpSpan SkASSERT "span->fOppValue >= 0"
    {57, "http___www_lptemp_com_.skp", true}, // addTCoincident oPeek = &other->fTs[++oPeekIndex];
    {71, "http___www_1milyonkahraman_org_.skp", true},  // addTCoincident SkASSERT(test->fT < 1);
    {88, "http___www_apuntesdelechuza_wordpress_com_.skp", true},  // bumpSpan SkASSERT "span->fOppValue >= 0"
    {89, "http___www_mobilizedconsulting_com_.skp", true}, // addTCancel SkASSERT(oIndex > 0);
    {93, "http___www_simple_living_in_suffolk_co_uk_.skp", true},  // bumpSpan SkASSERT "span->fOppValue >= 0"
};

size_t skipOverCount = sizeof(skipOver) / sizeof(skipOver[0]);


/* customize file in/out here */
/* TODO : add command flag interface */
#define CHROME_VERSION "1e5dfa4-4a995df"
#define SUMMARY_RUN 1

#ifdef SK_BUILD_FOR_WIN
    #define DRIVE_SPEC "D:"
    #define PATH_SLASH "\\"
#else
    #define DRIVE_SPEC ""
    #define PATH_SLASH "/"
#endif

#define IN_DIR_PRE  DRIVE_SPEC PATH_SLASH "skps"   PATH_SLASH "slave"
#define OUT_DIR_PRE DRIVE_SPEC PATH_SLASH "skpOut" PATH_SLASH "slave"
#define OUT_DIR_SUM DRIVE_SPEC PATH_SLASH "skpOut" PATH_SLASH "summary"
#define DIR_POST               PATH_SLASH "All"    PATH_SLASH CHROME_VERSION

static const char outOpDir[]     = "opClip";
static const char outOldDir[]    = "oldClip";
static const char outStatusDir[] = "statusTest";

static SkString get_in_path(int dirNo, const char* filename) {
    SkString path;
    SkASSERT(dirNo);
    path.appendf("%s%d%s", IN_DIR_PRE, dirNo, DIR_POST);
    if (!sk_exists(path.c_str())) {
        SkDebugf("could not read %s\n", path.c_str());
        return SkString();
    }
    if (filename) {
        path.appendf("%s%s", PATH_SLASH, filename);
        if (!sk_exists(path.c_str())) {
            SkDebugf("could not read %s\n", path.c_str());
            return SkString();
        }
    }
    return path;
}

static void make_recursive_dir(const SkString& path) {
    if (sk_exists(path.c_str())) {
        return;
    }
    const char* pathStr = path.c_str();
    int last = (int) path.size();
    do {
        while (last > 0 && pathStr[--last] != PATH_SLASH[0])
            ;
        SkASSERT(last > 0);
        SkString shorter(pathStr, last);
        if (sk_mkdir(shorter.c_str())) {
            break;
        }
    } while (true);
    do {
        while (last < (int) path.size() && pathStr[++last] != PATH_SLASH[0])
            ;
        SkString shorter(pathStr, last);
        SkAssertResult(sk_mkdir(shorter.c_str()));
    } while (last < (int) path.size());
}

static SkString get_out_path(int dirNo, const char* dirName) {
    SkString path;
    SkASSERT(dirNo);
    SkASSERT(dirName);
    path.appendf("%s%d%s%s%s", OUT_DIR_PRE, dirNo, DIR_POST, PATH_SLASH, dirName);
    make_recursive_dir(path);
    return path;
}

static SkString get_sum_path(const char* dirName) {
    SkString path;
    SkASSERT(dirName);
    path.appendf("%s%d%s%s", OUT_DIR_SUM, SUMMARY_RUN, PATH_SLASH, dirName);
    SkDebugf("%s\n", path.c_str());
    make_recursive_dir(path);
    return path;
}

static SkString make_png_name(const char* filename) {
    SkString pngName = SkString(filename);
    pngName.remove(pngName.size() - 3, 3);
    pngName.append("png");
    return pngName;
}

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

enum TestStep {
    kCompareBits,
    kEncodeFiles,
};

enum {
    kMaxLength = 256,
    kMaxFiles = 128,
    kSmallLimit = 1000,
};

struct TestResult {
    void init(int dirNo) {
        fDirNo = dirNo;
        sk_bzero(fFilename, sizeof(fFilename));
        fTestStep = kCompareBits;
        fScale = 1;
    }

    void init(int dirNo, const SkString& filename) {
        fDirNo = dirNo;
        strcpy(fFilename, filename.c_str());
        fTestStep = kCompareBits;
        fScale = 1;
    }

    SkString status() {
        SkString outStr;
        outStr.printf("%s %d %d\n", fFilename, fPixelError, fTime);
        return outStr;
    }

    SkString progress() {
        SkString outStr;
        outStr.printf("dir=%d %s ", fDirNo, fFilename);
        if (fPixelError) {
            outStr.appendf(" err=%d", fPixelError);
        }
        if (fTime) {
            outStr.appendf(" time=%d", fTime);
        }
        if (fScale != 1) {
            outStr.appendf(" scale=%d", fScale);
        }
        outStr.appendf("\n");
        return outStr;

    }

    void test(int dirNo, const SkString& filename) {
        init(dirNo);
        strcpy(fFilename, filename.c_str());
        testOne();
    }

    void testOne();

    char fFilename[kMaxLength];
    TestStep fTestStep;
    int fDirNo;
    int fPixelError;
    SkMSec fTime;
    int fScale;
};

class SortByPixel : public TestResult {
public:
    bool operator<(const SortByPixel& rh) const {
        return fPixelError < rh.fPixelError;
    }
};

class SortByTime : public TestResult {
public:
    bool operator<(const SortByTime& rh) const {
        return fTime < rh.fTime;
    }
};

class SortByName : public TestResult {
public:
    bool operator<(const SortByName& rh) const {
        return strcmp(fFilename, rh.fFilename) < 0;
    }
};

struct TestState {
    void init(int dirNo) {
        fResult.init(dirNo);
    }

    SkTDArray<SortByPixel> fPixelWorst;
    SkTDArray<SortByTime> fSlowest;
    TestResult fResult;
};

struct TestRunner {
    ~TestRunner();
    void render();
    SkTDArray<class TestRunnable*> fRunnables;
};

class TestRunnable {
public:
    void operator()() {
        SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024);
        (*fTestFun)(&fState);
    }

    TestState fState;
    void (*fTestFun)(TestState*);
};


class TestRunnableDir : public TestRunnable {
public:
    TestRunnableDir(void (*testFun)(TestState*), int dirNo, TestRunner* runner) {
        fState.init(dirNo);
        fTestFun = testFun;
    }

};

class TestRunnableFile : public TestRunnable {
public:
    TestRunnableFile(void (*testFun)(TestState*), int dirNo, const char* name, TestRunner* runner) {
        fState.init(dirNo);
        strcpy(fState.fResult.fFilename, name);
        fTestFun = testFun;
    }
};

class TestRunnableEncode : public TestRunnableFile {
public:
    TestRunnableEncode(void (*testFun)(TestState*), int dirNo, const char* name, TestRunner* runner)
        : TestRunnableFile(testFun, dirNo, name, runner) {
        fState.fResult.fTestStep = kEncodeFiles;
    }
};

TestRunner::~TestRunner() {
    for (int index = 0; index < fRunnables.count(); index++) {
        delete fRunnables[index];
    }
}

void TestRunner::render() {
    SkTaskGroup().batch(fRunnables.count(), [&](int i) {
        (*fRunnables[i])();
    });
}

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


static int similarBits(const SkBitmap& gr, const SkBitmap& sk) {
    const int kRowCount = 3;
    const int kThreshold = 3;
    int width = SkTMin(gr.width(), sk.width());
    if (width < kRowCount) {
        return true;
    }
    int height = SkTMin(gr.height(), sk.height());
    if (height < kRowCount) {
        return true;
    }
    int errorTotal = 0;
    SkTArray<int, true> errorRows;
    errorRows.push_back_n(width * kRowCount);
    SkAutoLockPixels autoGr(gr);
    SkAutoLockPixels autoSk(sk);
    for (int y = 0; y < height; ++y) {
        SkPMColor* grRow = gr.getAddr32(0, y);
        SkPMColor* skRow = sk.getAddr32(0, y);
        int* base = &errorRows[0];
        int* cOut = &errorRows[y % kRowCount];
        for (int x = 0; x < width; ++x) {
            SkPMColor grColor = grRow[x];
            SkPMColor skColor = skRow[x];
            int dr = SkGetPackedR32(grColor) - SkGetPackedR32(skColor);
            int dg = SkGetPackedG32(grColor) - SkGetPackedG32(skColor);
            int db = SkGetPackedB32(grColor) - SkGetPackedB32(skColor);
            int error = cOut[x] = SkTMax(SkAbs32(dr), SkTMax(SkAbs32(dg), SkAbs32(db)));
            if (error < kThreshold || x < 2) {
                continue;
            }
            if (base[x - 2] < kThreshold
                    || base[width + x - 2] < kThreshold
                    || base[width * 2 + x - 2] < kThreshold
                    || base[x - 1] < kThreshold
                    || base[width + x - 1] < kThreshold
                    || base[width * 2 + x - 1] < kThreshold
                    || base[x] < kThreshold
                    || base[width + x] < kThreshold
                    || base[width * 2 + x] < kThreshold) {
                continue;
            }
            errorTotal += error;
        }
    }
    return errorTotal;
}

static bool addError(TestState* data, const TestResult& testResult) {
    if (testResult.fPixelError <= 0 && testResult.fTime <= 0) {
        return false;
    }
    int worstCount = data->fPixelWorst.count();
    int pixelError = testResult.fPixelError;
    if (pixelError > 0) {
        for (int index = 0; index < worstCount; ++index) {
            if (pixelError > data->fPixelWorst[index].fPixelError) {
                data->fPixelWorst[index] = *(SortByPixel*) &testResult;
                return true;
            }
        }
    }
    int slowCount = data->fSlowest.count();
    SkMSec time = testResult.fTime;
    if (time > 0) {
        for (int index = 0; index < slowCount; ++index) {
            if (time > data->fSlowest[index].fTime) {
                data->fSlowest[index] = *(SortByTime*) &testResult;
                return true;
            }
        }
    }
    if (pixelError > 0 && worstCount < kMaxFiles) {
        *data->fPixelWorst.append() = *(SortByPixel*) &testResult;
        return true;
    }
    if (time > 0 && slowCount < kMaxFiles) {
        *data->fSlowest.append() = *(SortByTime*) &testResult;
        return true;
    }
    return false;
}

static SkMSec timePict(SkPicture* pic, SkCanvas* canvas) {
    canvas->save();
    SkScalar pWidth = pic->cullRect().width();
    SkScalar pHeight = pic->cullRect().height();
    const SkScalar maxDimension = 1000.0f;
    const int slices = 3;
    SkScalar xInterval = SkTMax(pWidth - maxDimension, 0.0f) / (slices - 1);
    SkScalar yInterval = SkTMax(pHeight - maxDimension, 0.0f) / (slices - 1);
    SkRect rect = {0, 0, SkTMin(maxDimension, pWidth), SkTMin(maxDimension, pHeight) };
    canvas->clipRect(rect);
    double start = SkTime::GetMSecs();
    for (int x = 0; x < slices; ++x) {
        for (int y = 0; y < slices; ++y) {
            pic->playback(canvas);
            canvas->translate(0, yInterval);
        }
        canvas->translate(xInterval, -yInterval * slices);
    }
    double end = SkTime::GetMSecs();
    canvas->restore();
    return static_cast<SkMSec>(end - start);
}

static void drawPict(SkPicture* pic, SkCanvas* canvas, int scale) {
    canvas->clear(SK_ColorWHITE);
    if (scale != 1) {
        canvas->save();
        canvas->scale(1.0f / scale, 1.0f / scale);
    }
    pic->playback(canvas);
    if (scale != 1) {
        canvas->restore();
    }
}

static void writePict(const SkBitmap& bitmap, const char* outDir, const char* pngName) {
    SkString outFile = get_sum_path(outDir);
    outFile.appendf("%s%s", PATH_SLASH, pngName);
    if (!SkImageEncoder::EncodeFile(outFile.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100)) {
        SkDebugf("unable to encode gr %s (width=%d height=%d)\n", pngName,
                    bitmap.width(), bitmap.height());
    }
}

void TestResult::testOne() {
    sk_sp<SkPicture> pic;
    {
    #if DEBUG_SHOW_TEST_NAME
        if (fTestStep == kCompareBits) {
            SkString testName(fFilename);
            const char http[] = "http";
            if (testName.startsWith(http)) {
                testName.remove(0, sizeof(http) - 1);
            }
            while (testName.startsWith("_")) {
                testName.remove(0, 1);
            }
            const char dotSkp[] = ".skp";
            if (testName.endsWith(dotSkp)) {
                size_t len = testName.size();
                testName.remove(len - (sizeof(dotSkp) - 1), sizeof(dotSkp) - 1);
            }
            testName.prepend("skp");
            testName.append("1");
            strncpy(DEBUG_FILENAME_STRING, testName.c_str(), DEBUG_FILENAME_STRING_LENGTH);
        } else if (fTestStep == kEncodeFiles) {
            strncpy(DEBUG_FILENAME_STRING, "", DEBUG_FILENAME_STRING_LENGTH);
        }
    #endif
        SkString path = get_in_path(fDirNo, fFilename);
        SkFILEStream stream(path.c_str());
        if (!stream.isValid()) {
            SkDebugf("invalid stream %s\n", path.c_str());
            return;
        }
        pic = SkPicture::MakeFromStream(&stream);
        if (!pic) {
            SkDebugf("unable to decode %s\n", fFilename);
            return;
        }
        SkScalar width = pic->cullRect().width();
        SkScalar height = pic->cullRect().height();
        SkBitmap oldBitmap, opBitmap;
        fScale = 1;
        while (width / fScale > 32767 || height / fScale > 32767) {
            ++fScale;
        }
        do {
            int dimX = SkScalarCeilToInt(width / fScale);
            int dimY = SkScalarCeilToInt(height / fScale);
            if (oldBitmap.tryAllocN32Pixels(dimX, dimY) && opBitmap.tryAllocN32Pixels(dimX, dimY)) {
                break;
            }
            SkDebugf("-%d-", fScale);
        } while (++fScale < 256);
        if (fScale >= 256) {
            SkDebugf("unable to allocate bitmap for %s (w=%f h=%f)\n", fFilename,
                    width, height);
            return;
        }
        oldBitmap.eraseColor(SK_ColorWHITE);
        SkCanvas oldCanvas(oldBitmap);
        oldCanvas.setAllowSimplifyClip(false);
        opBitmap.eraseColor(SK_ColorWHITE);
        SkCanvas opCanvas(opBitmap);
        opCanvas.setAllowSimplifyClip(true);
        drawPict(pic.get(), &oldCanvas, fScale);
        drawPict(pic.get(), &opCanvas, fScale);
        if (fTestStep == kCompareBits) {
            fPixelError = similarBits(oldBitmap, opBitmap);
            SkMSec oldTime = timePict(pic.get(), &oldCanvas);
            SkMSec opTime = timePict(pic.get(), &opCanvas);
            fTime = SkTMax(static_cast<SkMSec>(0), oldTime - opTime);
        } else if (fTestStep == kEncodeFiles) {
            SkString pngStr = make_png_name(fFilename);
            const char* pngName = pngStr.c_str();
            writePict(oldBitmap, outOldDir, pngName);
            writePict(opBitmap, outOpDir, pngName);
        }
    }
}

DEFINE_string2(match, m, "PathOpsSkpClipThreaded",
        "[~][^]substring[$] [...] of test name to run.\n"
        "Multiple matches may be separated by spaces.\n"
        "~ causes a matching test to always be skipped\n"
        "^ requires the start of the test to match\n"
        "$ requires the end of the test to match\n"
        "^ and $ requires an exact match\n"
        "If a test does not match any list entry,\n"
        "it is skipped unless some list entry starts with ~");
DEFINE_string2(dir, d, nullptr, "range of directories (e.g., 1-100)");
DEFINE_string2(skp, s, nullptr, "skp to test");
DEFINE_bool2(single, z, false, "run tests on a single thread internally.");
DEFINE_int32(testIndex, 0, "override local test index (PathOpsSkpClipOneOff only).");
DEFINE_bool2(verbose, v, false, "enable verbose output.");

static bool verbose() {
    return FLAGS_verbose;
}

class Dirs {
public:
    Dirs() {
        reset();
        sk_bzero(fRun, sizeof(fRun));
        fSet = false;
    }

    int first() const {
        int index = 0;
        while (++index < kMaxDir) {
            if (fRun[index]) {
                return index;
            }
        }
        SkASSERT(0);
        return -1;
    }

    int last() const {
        int index = kMaxDir;
        while (--index > 0 && !fRun[index])
            ;
        return index;
    }

    int next() {
        while (++fIndex < kMaxDir) {
            if (fRun[fIndex]) {
                return fIndex;
            }
        }
        return -1;
    }

    void reset() {
        fIndex = -1;
    }

    void set(int start, int end) {
        while (start < end) {
            fRun[start++] = 1;
        }
        fSet = true;
    }

    void setDefault() {
        if (!fSet) {
            set(1, 100);
        }
    }

private:
    enum {
         kMaxDir = 101
    };
    char fRun[kMaxDir];
    int fIndex;
    bool fSet;
} gDirs;

class Filenames {
public:
    Filenames()
        : fIndex(-1) {
    }

    const char* next() {
        while (fNames && ++fIndex < fNames->count()) {
            return (*fNames)[fIndex];
        }
        return nullptr;
    }

    void set(const SkCommandLineFlags::StringArray& names) {
        fNames = &names;
    }

private:
    int fIndex;
    const SkCommandLineFlags::StringArray* fNames;
} gNames;

static bool buildTestDir(int dirNo, int firstDirNo,
        SkTDArray<TestResult>* tests, SkTDArray<SortByName*>* sorted) {
    SkString dirName = get_out_path(dirNo, outStatusDir);
    if (!dirName.size()) {
        return false;
    }
    SkOSFile::Iter iter(dirName.c_str(), "skp");
    SkString filename;
    while (iter.next(&filename)) {
        TestResult test;
        test.init(dirNo);
        SkString spaceFile(filename);
        char* spaces = spaceFile.writable_str();
        int spaceSize = (int) spaceFile.size();
        for (int index = 0; index < spaceSize; ++index) {
            if (spaces[index] == '.') {
                spaces[index] = ' ';
            }
        }
        int success = sscanf(spaces, "%s %d %d skp", test.fFilename,
                &test.fPixelError, &test.fTime);
        if (success < 3) {
            SkDebugf("failed to scan %s matched=%d\n", filename.c_str(), success);
            return false;
        }
        *tests[dirNo - firstDirNo].append() = test;
    }
    if (!sorted) {
        return true;
    }
    SkTDArray<TestResult>& testSet = tests[dirNo - firstDirNo];
    int count = testSet.count();
    for (int index = 0; index < count; ++index) {
        *sorted[dirNo - firstDirNo].append() = (SortByName*) &testSet[index];
    }
    if (sorted[dirNo - firstDirNo].count()) {
        SkTQSort<SortByName>(sorted[dirNo - firstDirNo].begin(),
                sorted[dirNo - firstDirNo].end() - 1);
        if (verbose()) {
            SkDebugf("+");
        }
    }
    return true;
}

static void testSkpClip(TestState* data) {
    data->fResult.testOne();
    SkString statName(data->fResult.fFilename);
    SkASSERT(statName.endsWith(".skp"));
    statName.remove(statName.size() - 4, 4);
    statName.appendf(".%d.%d.skp", data->fResult.fPixelError, data->fResult.fTime);
    SkString statusFile = get_out_path(data->fResult.fDirNo, outStatusDir);
    if (!statusFile.size()) {
        SkDebugf("failed to create %s", statusFile.c_str());
        return;
    }
    statusFile.appendf("%s%s", PATH_SLASH, statName.c_str());
    FILE* file = sk_fopen(statusFile.c_str(), kWrite_SkFILE_Flag);
    if (!file) {
            SkDebugf("failed to create %s", statusFile.c_str());
            return;
    }
    sk_fclose(file);
    if (verbose()) {
        if (data->fResult.fPixelError || data->fResult.fTime) {
            SkDebugf("%s", data->fResult.progress().c_str());
        } else {
            SkDebugf(".");
        }
    }
}

bool Less(const SortByName& a, const SortByName& b);
bool Less(const SortByName& a, const SortByName& b) {
    return a < b;
}

static bool doOneDir(TestState* state, bool threaded) {
    int dirNo = state->fResult.fDirNo;
    SkString dirName = get_in_path(dirNo, nullptr);
    if (!dirName.size()) {
        return false;
    }
    SkTDArray<TestResult> tests[1];
    SkTDArray<SortByName*> sorted[1];
    if (!buildTestDir(dirNo, dirNo, tests, sorted)) {
        return false;
    }
    SkOSFile::Iter iter(dirName.c_str(), "skp");
    SkString filename;
    while (iter.next(&filename)) {
        for (size_t index = 0; index < skipOverCount; ++index) {
            if (skipOver[index].directory == dirNo
                    && strcmp(filename.c_str(), skipOver[index].filename) == 0) {
                goto checkEarlyExit;
            }
        }
        {
            SortByName name;
            name.init(dirNo);
            strncpy(name.fFilename, filename.c_str(), filename.size() - 4);  // drop .skp
            int count = sorted[0].count();
            int idx = SkTSearch<SortByName, Less>(sorted[0].begin(), count, &name, sizeof(&name));
            if (idx >= 0) {
                SortByName* found = sorted[0][idx];
                (void) addError(state, *found);
                continue;
            }
            TestResult test;
            test.init(dirNo, filename);
            state->fResult = test;
            testSkpClip(state);
#if 0 // artificially limit to a few while debugging code
            static int debugLimit = 0;
            if (++debugLimit == 5) {
                return true;
            }
#endif
        }
checkEarlyExit:
        ;
    }
    return true;
}

static void initTest() {
#if !defined SK_BUILD_FOR_WIN && !defined SK_BUILD_FOR_MAC
    SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true);
    SK_CONF_SET("images.png.suppressDecoderWarnings", true);
#endif
}

static void testSkpClipEncode(TestState* data) {
    data->fResult.testOne();
    if (verbose()) {
        SkDebugf("+");
    }
}

static void encodeFound(TestState& state) {
    if (verbose()) {
        if (state.fPixelWorst.count()) {
            SkTDArray<SortByPixel*> worst;
            for (int index = 0; index < state.fPixelWorst.count(); ++index) {
                *worst.append() = &state.fPixelWorst[index];
            }
            SkTQSort<SortByPixel>(worst.begin(), worst.end() - 1);
            for (int index = 0; index < state.fPixelWorst.count(); ++index) {
                const TestResult& result = *worst[index];
                SkDebugf("%d %s pixelError=%d\n", result.fDirNo, result.fFilename, result.fPixelError);
            }
        }
        if (state.fSlowest.count()) {
            SkTDArray<SortByTime*> slowest;
            for (int index = 0; index < state.fSlowest.count(); ++index) {
                *slowest.append() = &state.fSlowest[index];
            }
            if (slowest.count() > 0) {
                SkTQSort<SortByTime>(slowest.begin(), slowest.end() - 1);
                for (int index = 0; index < slowest.count(); ++index) {
                    const TestResult& result = *slowest[index];
                    SkDebugf("%d %s time=%d\n", result.fDirNo, result.fFilename, result.fTime);
                }
            }
        }
    }
    TestRunner testRunner;
    for (int index = 0; index < state.fPixelWorst.count(); ++index) {
        const TestResult& result = state.fPixelWorst[index];
        SkString filename(result.fFilename);
        if (!filename.endsWith(".skp")) {
            filename.append(".skp");
        }
        *testRunner.fRunnables.append() = new TestRunnableEncode(&testSkpClipEncode, result.fDirNo,
                                                                 filename.c_str(), &testRunner);
    }
    testRunner.render();
}

class Test {
public:
    Test() {}
    virtual ~Test() {}

    const char* getName() { onGetName(&fName); return fName.c_str(); }
    void run() { onRun(); }

protected:
    virtual void onGetName(SkString*) = 0;
    virtual void onRun() = 0;

private:
    SkString    fName;
};

typedef SkTRegistry<Test*(*)(void*)> TestRegistry;

#define DEF_TEST(name)                                                \
    static void test_##name();                                        \
    class name##Class : public Test {                                 \
    public:                                                           \
        static Test* Factory(void*) { return new name##Class; }       \
                                                                      \
    protected:                                                        \
        void onGetName(SkString* name) override { name->set(#name); } \
        void onRun() override { test_##name(); }                      \
    };                                                                \
    static TestRegistry gReg_##name##Class(name##Class::Factory);     \
    static void test_##name()

DEF_TEST(PathOpsSkpClip) {
    gDirs.setDefault();
    initTest();
    SkTArray<TestResult, true> errors;
    TestState state;
    state.init(0);
    int dirNo;
    gDirs.reset();
    while ((dirNo = gDirs.next()) > 0) {
        if (verbose()) {
            SkDebugf("dirNo=%d\n", dirNo);
        }
        state.fResult.fDirNo = dirNo;
        if (!doOneDir(&state, false)) {
            break;
        }
    }
    encodeFound(state);
}

static void testSkpClipMain(TestState* data) {
        (void) doOneDir(data, true);
}

DEF_TEST(PathOpsSkpClipThreaded) {
    gDirs.setDefault();
    initTest();
    TestRunner testRunner;
    int dirNo;
    gDirs.reset();
    while ((dirNo = gDirs.next()) > 0) {
        *testRunner.fRunnables.append() = new TestRunnableDir(&testSkpClipMain, dirNo, &testRunner);
    }
    testRunner.render();
    TestState state;
    state.init(0);
    gDirs.reset();
    while ((dirNo = gDirs.next()) > 0) {
        TestState& testState = testRunner.fRunnables[dirNo - 1]->fState;
        SkASSERT(testState.fResult.fDirNo == dirNo);
        for (int inner = 0; inner < testState.fPixelWorst.count(); ++inner) {
            addError(&state, testState.fPixelWorst[inner]);
        }
        for (int inner = 0; inner < testState.fSlowest.count(); ++inner) {
            addError(&state, testState.fSlowest[inner]);
        }
    }
    encodeFound(state);
}

static bool buildTests(SkTDArray<TestResult>* tests, SkTDArray<SortByName*>* sorted) {
    int firstDirNo = gDirs.first();
    int dirNo;
    while ((dirNo = gDirs.next()) > 0) {
        if (!buildTestDir(dirNo, firstDirNo, tests, sorted)) {
            return false;
        }
    }
    return true;
}

DEF_TEST(PathOpsSkpClipUberThreaded) {
    gDirs.setDefault();
    const int firstDirNo = gDirs.next();
    const int lastDirNo = gDirs.last();
    initTest();
    int dirCount = lastDirNo - firstDirNo + 1;
    SkAutoTDeleteArray<SkTDArray<TestResult> > tests(new SkTDArray<TestResult>[dirCount]);
    SkAutoTDeleteArray<SkTDArray<SortByName*> > sorted(new SkTDArray<SortByName*>[dirCount]);
    if (!buildTests(tests.get(), sorted.get())) {
        return;
    }
    TestRunner testRunner;
    int dirNo;
    gDirs.reset();
    while ((dirNo = gDirs.next()) > 0) {
        SkString dirName = get_in_path(dirNo, nullptr);
        if (!dirName.size()) {
            continue;
        }
        SkOSFile::Iter iter(dirName.c_str(), "skp");
        SkString filename;
        while (iter.next(&filename)) {
            for (size_t index = 0; index < skipOverCount; ++index) {
                if (skipOver[index].directory == dirNo
                        && strcmp(filename.c_str(), skipOver[index].filename) == 0) {
                    goto checkEarlyExit;
                }
            }
            {
                SortByName name;
                name.init(dirNo);
                strncpy(name.fFilename, filename.c_str(), filename.size() - 4);  // drop .skp
                int count = sorted.get()[dirNo - firstDirNo].count();
                if (SkTSearch<SortByName, Less>(sorted.get()[dirNo - firstDirNo].begin(),
                        count, &name, sizeof(&name)) < 0) {
                    *testRunner.fRunnables.append() = new TestRunnableFile(
                            &testSkpClip, dirNo, filename.c_str(), &testRunner);
                }
            }
    checkEarlyExit:
            ;
        }

    }
    testRunner.render();
    SkAutoTDeleteArray<SkTDArray<TestResult> > results(new SkTDArray<TestResult>[dirCount]);
    if (!buildTests(results.get(), nullptr)) {
        return;
    }
    SkTDArray<TestResult> allResults;
    for (int dirNo = firstDirNo; dirNo <= lastDirNo; ++dirNo) {
        SkTDArray<TestResult>& array = results.get()[dirNo - firstDirNo];
        allResults.append(array.count(), array.begin());
    }
    int allCount = allResults.count();
    SkTDArray<SortByPixel*> pixels;
    SkTDArray<SortByTime*> times;
    for (int index = 0; index < allCount; ++index) {
        *pixels.append() = (SortByPixel*) &allResults[index];
        *times.append() = (SortByTime*) &allResults[index];
    }
    TestState state;
    if (pixels.count()) {
        SkTQSort<SortByPixel>(pixels.begin(), pixels.end() - 1);
        for (int inner = 0; inner < kMaxFiles; ++inner) {
            *state.fPixelWorst.append() = *pixels[allCount - inner - 1];
        }
    }
    if (times.count()) {
        SkTQSort<SortByTime>(times.begin(), times.end() - 1);
        for (int inner = 0; inner < kMaxFiles; ++inner) {
            *state.fSlowest.append() = *times[allCount - inner - 1];
        }
    }
    encodeFound(state);
}

DEF_TEST(PathOpsSkpClipOneOff) {
    const int testIndex = FLAGS_testIndex;
    int dirNo = gDirs.next();
    if (dirNo < 0) {
        dirNo = skipOver[testIndex].directory;
    }
    const char* skp = gNames.next();
    if (!skp) {
        skp = skipOver[testIndex].filename;
    }
    initTest();
    SkAssertResult(get_in_path(dirNo, skp).size());
    SkString filename(skp);
    TestResult state;
    state.test(dirNo, filename);
    if (verbose()) {
        SkDebugf("%s", state.status().c_str());
    }
    state.fTestStep = kEncodeFiles;
    state.testOne();
}

DEF_TEST(PathOpsTestSkipped) {
    for (size_t index = 0; index < skipOverCount; ++index) {
        const SkipOverTest& skip = skipOver[index];
        if (!skip.blamePathOps) {
            continue;
        }
        int dirNo = skip.directory;
        const char* skp = skip.filename;
        initTest();
        SkAssertResult(get_in_path(dirNo, skp).size());
        SkString filename(skp);
        TestResult state;
        state.test(dirNo, filename);
        if (verbose()) {
            SkDebugf("%s", state.status().c_str());
        }
        state.fTestStep = kEncodeFiles;
        state.testOne();
    }
}

DEF_TEST(PathOpsCopyFails) {
    FLAGS_verbose = true;
    for (size_t index = 0; index < skipOverCount; ++index) {
        int dirNo = skipOver[index].directory;
        SkDebugf("mkdir -p " IN_DIR_PRE "%d" DIR_POST "\n", dirNo);
    }
    for (size_t index = 0; index < skipOverCount; ++index) {
        int dirNo = skipOver[index].directory;
        const char* filename = skipOver[index].filename;
        SkDebugf("rsync -av cary-linux.cnc:/tera" PATH_SLASH "skps" PATH_SLASH "slave"
            "%d" DIR_POST "/%s " IN_DIR_PRE "%d" DIR_POST "\n", dirNo, filename, dirNo);
    }
}

template TestRegistry* TestRegistry::gHead;

class Iter {
public:
    Iter() { this->reset(); }
    void reset() { fReg = TestRegistry::Head(); }

    Test* next() {
        if (fReg) {
            TestRegistry::Factory fact = fReg->factory();
            fReg = fReg->next();
            Test* test = fact(nullptr);
            return test;
        }
        return nullptr;
    }

private:
    const TestRegistry* fReg;
};

int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
    SetupCrashHandler();
    SkCommandLineFlags::SetUsage("");
    SkCommandLineFlags::Parse(argc, argv);
    SkGraphics::Init();
    SkString header("PathOps SkpClip:");
    if (!FLAGS_match.isEmpty()) {
        header.appendf(" --match");
        for (int index = 0; index < FLAGS_match.count(); ++index) {
            header.appendf(" %s", FLAGS_match[index]);
        }
    }
    if (!FLAGS_dir.isEmpty()) {
        int count = FLAGS_dir.count();
        for (int i = 0; i < count; ++i) {
            const char* range = FLAGS_dir[i];
            const char* dash = strchr(range, '-');
            if (!dash) {
                dash = strchr(range, ',');
            }
            int first = atoi(range);
            int last = dash ? atoi(dash + 1) : first;
            if (!first || !last) {
                SkDebugf("couldn't parse --dir %s\n", range);
                return 1;
            }
            gDirs.set(first, last);
        }
    }
    if (!FLAGS_skp.isEmpty()) {
        gNames.set(FLAGS_skp);
    }
#ifdef SK_DEBUG
    header.append(" SK_DEBUG");
#else
    header.append(" SK_RELEASE");
#endif
    if (FLAGS_verbose) {
        header.appendf("\n");
    }
    SkDebugf("%s", header.c_str());
    Iter iter;
    Test* test;
    while ((test = iter.next()) != nullptr) {
        SkAutoTDelete<Test> owned(test);
        if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, test->getName())) {
            test->run();
        }
    }
    return 0;
}

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