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

#include <set>
#include <string>
#include <emscripten.h>
#include <emscripten/bind.h>
#include <emscripten/html5.h>

#include "gm/gm.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkData.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkStream.h"
#include "include/core/SkSurface.h"
#include "include/gpu/GrContextOptions.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/gl/GrGLInterface.h"
#include "include/gpu/gl/GrGLTypes.h"
#include "modules/canvaskit/WasmCommon.h"
#include "src/core/SkFontMgrPriv.h"
#include "src/core/SkMD5.h"
#include "tests/Test.h"
#include "tests/TestHarness.h"
#include "tools/HashAndEncode.h"
#include "tools/ResourceFactory.h"
#include "tools/flags/CommandLineFlags.h"
#include "tools/fonts/TestFontMgr.h"

using namespace emscripten;

/**
 * Returns a JS array of strings containing the names of the registered GMs. GMs are only registered
 * when their source is included in the "link" step, not if they are in something like libgm.a.
 * The names are also logged to the console.
 */
static JSArray ListGMs() {
    SkDebugf("Listing GMs\n");
    JSArray gms = emscripten::val::array();
    for (skiagm::GMFactory fact : skiagm::GMRegistry::Range()) {
        std::unique_ptr<skiagm::GM> gm(fact());
        SkDebugf("gm %s\n", gm->getName());
        gms.call<void>("push", std::string(gm->getName()));
    }
    return gms;
}

static std::unique_ptr<skiagm::GM> getGMWithName(std::string name) {
    for (skiagm::GMFactory fact : skiagm::GMRegistry::Range()) {
        std::unique_ptr<skiagm::GM> gm(fact());
        if (gm->getName() == name) {
            return gm;
        }
    }
    return nullptr;
}

/**
 * Sets the given WebGL context to be "current" and then creates a GrDirectContext from that
 * context.
 */
static sk_sp<GrDirectContext> MakeGrContext(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context)
{
    EMSCRIPTEN_RESULT r = emscripten_webgl_make_context_current(context);
    if (r < 0) {
        printf("failed to make webgl context current %d\n", r);
        return nullptr;
    }
    // setup GrDirectContext
    auto interface = GrGLMakeNativeInterface();
    // setup contexts
    sk_sp<GrDirectContext> dContext((GrDirectContext::MakeGL(interface)));
    return dContext;
}

static std::set<std::string> gKnownDigests;

static void LoadKnownDigest(std::string md5) {
  gKnownDigests.insert(md5);
}

static std::map<std::string, sk_sp<SkData>> gResources;

static sk_sp<SkData> getResource(const char* name) {
  auto it = gResources.find(name);
  if (it == gResources.end()) {
    SkDebugf("Resource %s not found\n", name);
    return nullptr;
  }
  return it->second;
}

static void LoadResource(std::string name, WASMPointerU8 bPtr, size_t len) {
  const uint8_t* bytes = reinterpret_cast<const uint8_t*>(bPtr);
  auto data = SkData::MakeFromMalloc(bytes, len);
  gResources[name] = std::move(data);

  if (!gResourceFactory) {
    gResourceFactory = getResource;
  }
}

/**
 * Runs the given GM and returns a JS object. If the GM was successful, the object will have the
 * following properties:
 *   "png" - a Uint8Array of the PNG data extracted from the surface.
 *   "hash" - a string which is the md5 hash of the pixel contents and the metadata.
 */
static JSObject RunGM(sk_sp<GrDirectContext> ctx, std::string name) {
    JSObject result = emscripten::val::object();
    auto gm = getGMWithName(name);
    if (!gm) {
        SkDebugf("Could not find gm with name %s\n", name.c_str());
        return result;
    }
    // TODO(kjlubick) make these configurable somehow. This probably makes sense to do as function
    //   parameters.
    auto alphaType = SkAlphaType::kPremul_SkAlphaType;
    auto colorType = SkColorType::kN32_SkColorType;
    SkISize size = gm->getISize();
    SkImageInfo info = SkImageInfo::Make(size, colorType, alphaType);
    sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(
            ctx.get(), skgpu::Budgeted::kYes, info, 0, kBottomLeft_GrSurfaceOrigin, nullptr, true));
    if (!surface) {
        SkDebugf("Could not make surface\n");
        return result;
    }
    auto canvas = surface->getCanvas();

    gm->onceBeforeDraw();
    SkString msg;
    // Based on GMSrc::draw from DM.
    auto gpuSetupResult = gm->gpuSetup(canvas, &msg);
    if (gpuSetupResult == skiagm::DrawResult::kFail) {
        SkDebugf("Error with gpu setup for gm %s: %s\n", name.c_str(), msg.c_str());
        return result;
    } else if (gpuSetupResult == skiagm::DrawResult::kSkip) {
        return result;
    }

    auto drawResult = gm->draw(canvas, &msg);
    if (drawResult == skiagm::DrawResult::kFail) {
        SkDebugf("Error with gm %s: %s\n", name.c_str(), msg.c_str());
        return result;
    } else if (drawResult == skiagm::DrawResult::kSkip) {
        return result;
    }
    surface->flushAndSubmit(true);

    // Based on GPUSink::readBack
    SkBitmap bitmap;
    bitmap.allocPixels(info);
    if (!canvas->readPixels(bitmap, 0, 0)) {
        SkDebugf("Could not read pixels back\n");
        return result;
    }

    // Now we need to encode to PNG and get the md5 hash of the pixels (and colorspace and stuff).
    // This is based on Task::Run from DM.cpp
    std::unique_ptr<HashAndEncode> hashAndEncode = std::make_unique<HashAndEncode>(bitmap);
    SkString md5;
    SkMD5 hash;
    hashAndEncode->feedHash(&hash);
    SkMD5::Digest digest = hash.finish();
    for (int i = 0; i < 16; i++) {
        md5.appendf("%02x", digest.data[i]);
    }

    auto ok = gKnownDigests.find(md5.c_str());
    if (ok == gKnownDigests.end()) {
        // We only need to decode the image if it is "interesting", that is, we have not written it
        // before to disk and uploaded it to gold.
        SkDynamicMemoryWStream stream;
        // We do not need to include the keys because they are optional - they are not read by Gold.
        CommandLineFlags::StringArray empty;
        hashAndEncode->encodePNG(&stream, md5.c_str(), empty, empty);

        auto data = stream.detachAsData();

        // This is the cleanest way to create a new Uint8Array with a copy of the data that is not
        // in the WASM heap. kjlubick tried returning a pointer inside an SkData, but that lead to
        // some use after free issues. By making the copy using the JS transliteration, we don't
        // risk the SkData object being cleaned up before we make the copy.
        Uint8Array pngData = emscripten::val(
            // https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#memory-views
            typed_memory_view(data->size(), data->bytes())
        ).call<Uint8Array>("slice"); // slice with no args makes a copy of the memory view.

        result.set("png", pngData);
        gKnownDigests.emplace(md5.c_str());
    }
    result.set("hash", md5.c_str());
    return result;
}

static JSArray ListTests() {
    SkDebugf("Listing Tests\n");
    JSArray tests = emscripten::val::array();
    for (auto test : skiatest::TestRegistry::Range()) {
        SkDebugf("test %s\n", test.fName);
        tests.call<void>("push", std::string(test.fName));
    }
    return tests;
}

static skiatest::Test getTestWithName(std::string name, bool* ok) {
    for (auto test : skiatest::TestRegistry::Range()) {
        if (name == test.fName) {
          *ok = true;
          return test;
        }
    }
    *ok = false;
    return skiatest::Test::MakeCPU(nullptr, nullptr);
}

// Based on DM.cpp:run_test
struct WasmReporter : public skiatest::Reporter {
    WasmReporter(std::string name, JSObject result): fName(name), fResult(result){}

    void reportFailed(const skiatest::Failure& failure) override {
        SkDebugf("Test %s failed: %s\n", fName.c_str(), failure.toString().c_str());
        fResult.set("result", "failed");
        fResult.set("msg", failure.toString().c_str());
    }
    std::string fName;
    JSObject fResult;
};

/**
 * Runs the given Test and returns a JS object. If the Test was located, the object will have the
 * following properties:
 *   "result" : One of "passed", "failed", "skipped".
 *   "msg": May be non-empty on failure
 */
static JSObject RunTest(std::string name) {
    JSObject result = emscripten::val::object();
    bool ok = false;
    auto test = getTestWithName(name, &ok);
    if (!ok) {
        SkDebugf("Could not find test with name %s\n", name.c_str());
        return result;
    }
    GrContextOptions grOpts;
    if (test.fTestType == skiatest::TestType::kGanesh) {
        result.set("result", "passed"); // default to passing - the reporter will mark failed.
        WasmReporter reporter(name, result);
        test.modifyGrContextOptions(&grOpts);
        test.ganesh(&reporter, grOpts);
        return result;
    } else if (test.fTestType == skiatest::TestType::kGraphite) {
        SkDebugf("Graphite test %s not yet supported\n", name.c_str());
        return result;
    }

    result.set("result", "passed"); // default to passing - the reporter will mark failed.
    WasmReporter reporter(name, result);
    test.cpu(&reporter);
    return result;
}

namespace skiatest {

using ContextType = sk_gpu_test::GrContextFactory::ContextType;

// These are the supported GrContextTypeFilterFn. They are defined in Test.h and implemented here.
bool IsGLContextType(ContextType ct) {
    return GrBackendApi::kOpenGL == sk_gpu_test::GrContextFactory::ContextTypeBackend(ct);
}
bool IsRenderingGLContextType(ContextType ct) {
    return IsGLContextType(ct) && sk_gpu_test::GrContextFactory::IsRenderingContext(ct);
}
bool IsMockContextType(ContextType ct) {
    return ct == ContextType::kMock_ContextType;
}
// These are not supported
bool IsVulkanContextType(ContextType) {return false;}
bool IsMetalContextType(ContextType) {return false;}
bool IsDirect3DContextType(ContextType) {return false;}
bool IsDawnContextType(ContextType) {return false;}

void RunWithGaneshTestContexts(GrContextTestFn* testFn, GrContextTypeFilterFn* filter,
                               Reporter* reporter, const GrContextOptions& options) {
    for (auto contextType : {ContextType::kGLES_ContextType, ContextType::kMock_ContextType}) {
        if (filter && !(*filter)(contextType)) {
            continue;
        }

        sk_gpu_test::GrContextFactory factory(options);
        sk_gpu_test::ContextInfo ctxInfo = factory.getContextInfo(contextType);

        REPORTER_ASSERT(reporter, ctxInfo.directContext() != nullptr);
        if (!ctxInfo.directContext()) {
            return;
        }
        ctxInfo.testContext()->makeCurrent();
        // From DMGpuTestProcs.cpp
        (*testFn)(reporter, ctxInfo);
        // Sync so any release/finished procs get called.
        ctxInfo.directContext()->flushAndSubmit(/*sync*/true);
    }
}
} // namespace skiatest

namespace {

// A GLtestContext that we can return from CreatePlatformGLTestContext below.
// It doesn't have to do anything WebGL-specific that I know of but we can't return
// a GLTestContext because it has pure virtual methods that need to be implemented.
class WasmWebGlTestContext : public sk_gpu_test::GLTestContext {
public:
    WasmWebGlTestContext() {}
    ~WasmWebGlTestContext() override {
        this->teardown();
    }
    // We assume WebGL only has one context and that it is always current.
    // Therefore these context related functions return null intentionally.
    // It's possible that more tests will pass if these were correctly implemented.
    std::unique_ptr<GLTestContext> makeNew() const override {
        // This is supposed to create a new GL context in a new GLTestContext.
        // Specifically for tests that do not want to re-use the existing one.
        return nullptr;
    }
    void onPlatformMakeNotCurrent() const override { }
    void onPlatformMakeCurrent() const override { }
    std::function<void()> onPlatformGetAutoContextRestore() const override {
        return nullptr;
    }
    GrGLFuncPtr onPlatformGetProcAddress(const char* procName) const override {
        return nullptr;
    }
};
} // namespace

namespace sk_gpu_test {
GLTestContext *CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
                                           GLTestContext *shareContext) {
    return new WasmWebGlTestContext();
}
} // namespace sk_gpu_test

void Init() {
    // Use the portable fonts.
    gSkFontMgr_DefaultFactory = &ToolUtils::MakePortableFontMgr;
}

TestHarness CurrentTestHarness() {
    return TestHarness::kWasmGMTests;
}

EMSCRIPTEN_BINDINGS(GMs) {
    function("Init", &Init);
    function("ListGMs", &ListGMs);
    function("ListTests", &ListTests);
    function("LoadKnownDigest", &LoadKnownDigest);
    function("_LoadResource", &LoadResource);
    function("MakeGrContext", &MakeGrContext);
    function("RunGM", &RunGM);
    function("RunTest", &RunTest);

    class_<GrDirectContext>("GrDirectContext")
        .smart_ptr<sk_sp<GrDirectContext>>("sk_sp<GrDirectContext>");
}
