// Main binary for DM.
// For a high-level overview, please see dm/README.

#include "LazyDecodeBitmap.h"
#include "SkCommonFlags.h"
#include "SkForceLinking.h"
#include "SkGraphics.h"
#include "SkOSFile.h"
#include "SkPicture.h"
#include "SkString.h"
#include "SkTaskGroup.h"
#include "Test.h"
#include "gm.h"
#include "sk_tool_utils.h"
#include "sk_tool_utils_flags.h"

#include "DMCpuGMTask.h"
#include "DMGpuGMTask.h"
#include "DMGpuSupport.h"
#include "DMJsonWriter.h"
#include "DMPDFTask.h"
#include "DMReporter.h"
#include "DMSKPTask.h"
#include "DMTask.h"
#include "DMTaskRunner.h"
#include "DMTestTask.h"

#ifdef SK_BUILD_POPPLER
#  include "SkPDFRasterizer.h"
#  define RASTERIZE_PDF_PROC SkPopplerRasterizePDF
#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
#  include "SkCGUtils.h"
#  define RASTERIZE_PDF_PROC SkPDFDocumentToBitmap
#else
#  define RASTERIZE_PDF_PROC NULL
#endif

#include <ctype.h>

using skiagm::GM;
using skiagm::GMRegistry;
using skiatest::Test;
using skiatest::TestRegistry;

static const char kGpuAPINameGL[] = "gl";
static const char kGpuAPINameGLES[] = "gles";

DEFINE_bool(gms, true, "Run GMs?");
DEFINE_bool(tests, true, "Run tests?");
DEFINE_bool(reportUsedChars, false, "Output test font construction data to be pasted into"
                                    " create_test_font.cpp.");

__SK_FORCE_IMAGE_DECODER_LINKING;

// "FooBar" -> "foobar".  Obviously, ASCII only.
static SkString lowercase(SkString s) {
    for (size_t i = 0; i < s.size(); i++) {
        s[i] = tolower(s[i]);
    }
    return s;
}

static const GrContextFactory::GLContextType native = GrContextFactory::kNative_GLContextType;
static const GrContextFactory::GLContextType nvpr   = GrContextFactory::kNVPR_GLContextType;
static const GrContextFactory::GLContextType null   = GrContextFactory::kNull_GLContextType;
static const GrContextFactory::GLContextType debug  = GrContextFactory::kDebug_GLContextType;
#if SK_ANGLE
static const GrContextFactory::GLContextType angle  = GrContextFactory::kANGLE_GLContextType;
#endif
#if SK_MESA
static const GrContextFactory::GLContextType mesa   = GrContextFactory::kMESA_GLContextType;
#endif

static void kick_off_gms(const SkTDArray<GMRegistry::Factory>& gms,
                         const SkTArray<SkString>& configs,
                         GrGLStandard gpuAPI,
                         DM::Reporter* reporter,
                         DM::TaskRunner* tasks) {
#define START(name, type, ...)                                                              \
    if (lowercase(configs[j]).equals(name)) {                                               \
        tasks->add(SkNEW_ARGS(DM::type, (name, reporter, tasks, gms[i], ## __VA_ARGS__)));  \
    }
    for (int i = 0; i < gms.count(); i++) {
        for (int j = 0; j < configs.count(); j++) {

            START("565",        CpuGMTask, kRGB_565_SkColorType);
            START("8888",       CpuGMTask, kN32_SkColorType);
            START("gpu",        GpuGMTask, native, gpuAPI, 0,  false);
            START("msaa4",      GpuGMTask, native, gpuAPI, 4,  false);
            START("msaa16",     GpuGMTask, native, gpuAPI, 16, false);
            START("nvprmsaa4",  GpuGMTask, nvpr,   gpuAPI, 4,  false);
            START("nvprmsaa16", GpuGMTask, nvpr,   gpuAPI, 16, false);
            START("gpudft",     GpuGMTask, native, gpuAPI, 0,  true);
            START("gpunull",    GpuGMTask, null,   gpuAPI, 0,  false);
            START("gpudebug",   GpuGMTask, debug,  gpuAPI, 0,  false);
#if SK_ANGLE
            START("angle",      GpuGMTask, angle,  gpuAPI, 0,  false);
#endif
#if SK_MESA
            START("mesa",       GpuGMTask, mesa,   gpuAPI, 0,  false);
#endif
            START("pdf",        PDFTask,   RASTERIZE_PDF_PROC);
        }
    }
#undef START
}

static void kick_off_tests(const SkTDArray<TestRegistry::Factory>& tests,
                           DM::Reporter* reporter,
                           DM::TaskRunner* tasks) {
    for (int i = 0; i < tests.count(); i++) {
        SkAutoTDelete<Test> test(tests[i](NULL));
        if (test->isGPUTest()) {
            tasks->add(SkNEW_ARGS(DM::GpuTestTask, (reporter, tasks, tests[i])));
        } else {
            tasks->add(SkNEW_ARGS(DM::CpuTestTask, (reporter, tasks, tests[i])));
        }
    }
}

static void find_skps(SkTArray<SkString>* skps) {
    if (FLAGS_skps.isEmpty()) {
        return;
    }

    SkOSFile::Iter it(FLAGS_skps[0], ".skp");
    SkString filename;
    while (it.next(&filename)) {
        if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, filename.c_str())) {
            skps->push_back(SkOSPath::Join(FLAGS_skps[0], filename.c_str()));
        }
    }
}

static void kick_off_skps(const SkTArray<SkString>& skps,
                          DM::Reporter* reporter,
                          DM::TaskRunner* tasks) {
    for (int i = 0; i < skps.count(); ++i) {
        SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(skps[i].c_str()));
        if (stream.get() == NULL) {
            SkDebugf("Could not read %s.\n", skps[i].c_str());
            exit(1);
        }
        SkAutoTUnref<SkPicture> pic(
                SkPicture::CreateFromStream(stream.get(), &sk_tools::LazyDecodeBitmap));
        if (pic.get() == NULL) {
            SkDebugf("Could not read %s as an SkPicture.\n", skps[i].c_str());
            exit(1);
        }

        SkString filename = SkOSPath::Basename(skps[i].c_str());
        tasks->add(SkNEW_ARGS(DM::SKPTask, (reporter, tasks, pic, filename)));
        tasks->add(SkNEW_ARGS(DM::PDFTask, (reporter, tasks, pic, filename, RASTERIZE_PDF_PROC)));
    }
}

static void report_failures(const SkTArray<SkString>& failures) {
    if (failures.count() == 0) {
        return;
    }

    SkDebugf("Failures:\n");
    for (int i = 0; i < failures.count(); i++) {
        SkDebugf("  %s\n", failures[i].c_str());
    }
    SkDebugf("%d failures.\n", failures.count());
}

static GrGLStandard get_gl_standard() {
  if (FLAGS_gpuAPI.contains(kGpuAPINameGL)) {
      return kGL_GrGLStandard;
  }
  if (FLAGS_gpuAPI.contains(kGpuAPINameGLES)) {
      return kGLES_GrGLStandard;
  }
  return kNone_GrGLStandard;
}

template <typename T, typename Registry>
static void append_matching_factories(Registry* head, SkTDArray<typename Registry::Factory>* out) {
    for (const Registry* reg = head; reg != NULL; reg = reg->next()) {
        SkAutoTDelete<T> forName(reg->factory()(NULL));
        if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, forName->getName())) {
            *out->append() = reg->factory();
        }
    }
}

int dm_main() {
    SkAutoGraphics ag;
    SkTaskGroup::Enabler enabled(FLAGS_threads);

    if (FLAGS_dryRun || FLAGS_veryVerbose) {
        FLAGS_verbose = true;
    }
#if SK_ENABLE_INST_COUNT
    gPrintInstCount = FLAGS_leaks;
#endif

    SkTArray<SkString> configs;
    for (int i = 0; i < FLAGS_config.count(); i++) {
        SkStrSplit(FLAGS_config[i], ", ", &configs);
    }

    GrGLStandard gpuAPI = get_gl_standard();

    SkTDArray<GMRegistry::Factory> gms;
    if (FLAGS_gms) {
        append_matching_factories<GM>(GMRegistry::Head(), &gms);
    }

    SkTDArray<TestRegistry::Factory> tests;
    if (FLAGS_tests) {
        append_matching_factories<Test>(TestRegistry::Head(), &tests);
    }

    SkTArray<SkString> skps;
    find_skps(&skps);

    SkDebugf("%d GMs x %d configs, %d tests, %d pictures\n",
             gms.count(), configs.count(), tests.count(), skps.count());
    DM::Reporter reporter;

    DM::TaskRunner tasks;
    kick_off_tests(tests, &reporter, &tasks);
    kick_off_gms(gms, configs, gpuAPI, &reporter, &tasks);
    kick_off_skps(skps, &reporter, &tasks);
    tasks.wait();

    DM::JsonWriter::DumpJson();

    SkDebugf("\n");
#ifdef SK_DEBUG
    if (FLAGS_portableFonts && FLAGS_reportUsedChars) {
        sk_tool_utils::report_used_chars();
    }
#endif

    SkTArray<SkString> failures;
    reporter.getFailures(&failures);
    report_failures(failures);
    return failures.count() > 0;
}
