/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <iostream>
#include <sys/stat.h>

#include "tools/skqp/src/skqp.h"

#include "include/core/SkData.h"
#include "src/core/SkOSFile.h"
#include "tools/Resources.h"

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

namespace {
class StdAssetManager : public SkQPAssetManager {
public:
    StdAssetManager(const char* p) : fPrefix(p) {
        SkASSERT(!fPrefix.empty());
        //TODO(halcanary): does this need to be changed if I run SkQP in Windows?
        fPrefix += "/";
    }
    sk_sp<SkData> open(const char* path) override {
        return SkData::MakeFromFileName((fPrefix + path).c_str());
    }
private:
    std::string fPrefix;
};

struct Args {
  char *assetDir;
  char *renderTests;
  char *outputDir;
};
}

static constexpr char kSkipUsage[] =
    " TEST_MATCH_RULES:"
    "    [~][^]substring[$] [...] of name to run.\n"
    "    Multiple matches may be separated by spaces.\n"
    "    ~ causes a matching name to always be skipped\n"
    "    ^ requires the start of the name to match\n"
    "    $ requires the end of the name to match\n"
    "    ^ and $ requires an exact match\n"
    "    If a name does not match any list entry,\n"
    "    it is skipped unless some list entry starts with ~\n";

static bool should_skip(const char* const* rules, size_t count, const char* name) {
    size_t testLen = strlen(name);
    bool anyExclude = count == 0;
    for (size_t i = 0; i < count; ++i) {
        const char* matchName = rules[i];
        size_t matchLen = strlen(matchName);
        bool matchExclude, matchStart, matchEnd;
        if ((matchExclude = matchName[0] == '~')) {
            anyExclude = true;
            matchName++;
            matchLen--;
        }
        if ((matchStart = matchName[0] == '^')) {
            matchName++;
            matchLen--;
        }
        if ((matchEnd = matchName[matchLen - 1] == '$')) {
            matchLen--;
        }
        if (matchStart ? (!matchEnd || matchLen == testLen)
                && strncmp(name, matchName, matchLen) == 0
                : matchEnd ? matchLen <= testLen
                && strncmp(name + testLen - matchLen, matchName, matchLen) == 0
                : strstr(name, matchName) != nullptr) {
            return matchExclude;
        }
    }
    return !anyExclude;
}

static void parse_args(int argc, char *argv[], Args *args) {
  if (argc < 4) {
      std::cerr << "Usage:\n  " << argv[0]
                << " ASSET_DIR RENDER_TESTS OUTPUT_DIR [TEST_MATCH_RULES]\n"
                << kSkipUsage << '\n';
      exit(1);
  }
  args->assetDir = argv[1];
  args->renderTests = argv[2];
  args->outputDir = argv[3];
}

int main(int argc, char *argv[]) {
    Args args;
    parse_args(argc, argv, &args);

    SetResourcePath(std::string(args.assetDir + std::string("/resources")).c_str());
    if (!sk_mkdir(args.outputDir)) {
        std::cerr << "sk_mkdir(" << args.outputDir << ") failed.\n";
        return 2;
    }
    StdAssetManager mgr(args.assetDir);
    SkQP skqp;
    skqp.init(&mgr, args.renderTests, args.outputDir);
    int ret = 0;

    const char* const* matchRules = &argv[4];
    size_t matchRulesCount = (size_t)(argc - 4);

    // Rendering Tests
    std::ostream& out = std::cout;
    for (auto backend : skqp.getSupportedBackends()) {
        auto testPrefix = std::string(SkQP::GetBackendName(backend)) + "_";
        for (auto gmFactory : skqp.getGMs()) {
            auto testName = testPrefix + SkQP::GetGMName(gmFactory);
            if (should_skip(matchRules, matchRulesCount, testName.c_str())) {
                continue;
            }
            out << "Starting: " << testName << std::endl;
            SkQP::RenderOutcome outcome;
            std::string except;

            std::tie(outcome, except) = skqp.evaluateGM(backend, gmFactory);
            if (!except.empty()) {
                out << "ERROR:    " << testName << " (" << except << ")\n";
                ret = 1;
            } else if (outcome.fMaxError != 0) {
                out << "FAILED:   " << testName << " (" << outcome.fMaxError << ")\n";
                ret = 1;
            } else {
                out << "Passed:   " << testName << "\n";
            }
            out.flush();
        }
    }

    // Unit Tests
    for (auto test : skqp.getUnitTests()) {
        auto testName = std::string("unitTest_") +  SkQP::GetUnitTestName(test);
        if (should_skip(matchRules, matchRulesCount, testName.c_str())) {
            continue;
        }
        out << "Starting test: " << testName << std::endl;
        std::vector<std::string> errors = skqp.executeTest(test);
        if (!errors.empty()) {
            out << "TEST FAILED (" << errors.size() << "): " << testName << "\n";
            for (const std::string& error : errors) {
                out << error << "\n";
            }
            ret = 1;
        } else {
            out << "Test passed:   " << testName << "\n";
        }
        out.flush();
    }
    skqp.makeReport();

    return ret;
}
