/*
 * Copyright 2022 Rive
 */

// Don't compile this file as part of the "tests" project.
#ifndef TESTING

#include "gm.hpp"
#include "common/testing_window.hpp"
#include "common/test_harness.hpp"

#ifdef RIVE_ANDROID
#include "common/rive_android_app.hpp"
#include <sys/system_properties.h>
#endif

#include <functional>

using namespace rivegm;

static bool verbose = false;
std::vector<std::tuple<std::function<GM*(void)>, std::string>> gmRegistry;
extern "C" void gms_build_registry()
{
    // Only call gms_build_registry() once!
    assert(gmRegistry.empty());

#define MAKE_GM(NAME)                                                          \
    extern GM* RIVE_MACRO_CONCAT(make_, NAME)();                               \
    gmRegistry.emplace_back(RIVE_MACRO_CONCAT(make_, NAME), #NAME);

    // Add slow GMs first so they get more time to run in a multiprocess
    // execution.
    MAKE_GM(hittest_nonZero)
    MAKE_GM(hittest_evenOdd)
    MAKE_GM(mandoline)
    MAKE_GM(lots_of_images)
    MAKE_GM(lots_of_images_sampled)
    MAKE_GM(feathertext_roboto)
    MAKE_GM(feathertext_montserrat)

    // Add the normal (not slow) gms last.
    MAKE_GM(batchedconvexpaths)
    MAKE_GM(batchedtriangulations)
    MAKE_GM(bevel180strokes)
    MAKE_GM(beziers)
    MAKE_GM(bug615686)
    MAKE_GM(cliprectintersections)
    MAKE_GM(cliprects)
    MAKE_GM(concavepaths)
    MAKE_GM(convexpaths)
    MAKE_GM(convex_lineonly_ths)
    MAKE_GM(crbug_996140)
    MAKE_GM(cubicpath)
    MAKE_GM(cubicclosepath)
    MAKE_GM(clippedcubic)
    MAKE_GM(clippedcubic2)
    MAKE_GM(bug5099)
    MAKE_GM(bug6083)
    MAKE_GM(degengrad)
    MAKE_GM(dstreadshuffle)
    MAKE_GM(emptyclear)
    MAKE_GM(emptytransparentclear)
    MAKE_GM(feather_shapes)
    MAKE_GM(feather_corner)
    MAKE_GM(feather_roundcorner)
    MAKE_GM(feather_ellipse)
    MAKE_GM(feather_cusp)
    MAKE_GM(feather_strokes)
    MAKE_GM(image)
    MAKE_GM(image_filter_options)
    MAKE_GM(image_aa_border)
    MAKE_GM(image_lod)
    MAKE_GM(interleavedfeather)
    MAKE_GM(interleavedfillrule)
    MAKE_GM(labyrinth_square)
    MAKE_GM(labyrinth_round)
    MAKE_GM(labyrinth_butt)
    MAKE_GM(lots_of_grads_simple)
    MAKE_GM(lots_of_grads_complex)
    MAKE_GM(lots_of_grad_spans)
    MAKE_GM(lots_of_grads_clipped)
    MAKE_GM(lots_of_grads_mixed)
    MAKE_GM(mesh)
    MAKE_GM(mesh_ht_7)
    MAKE_GM(mesh_ht_1)
    MAKE_GM(mutating_fill_rule)
    MAKE_GM(oval)
    MAKE_GM(OverStroke)
    MAKE_GM(parallelclips)
    MAKE_GM(pathfill)
    MAKE_GM(rotatedcubicpath)
    MAKE_GM(bug7792)
    MAKE_GM(path_stroke_clip_crbug1070835)
    MAKE_GM(path_skbug_11859)
    MAKE_GM(path_skbug_11886)
    MAKE_GM(poly_nonZero)
    MAKE_GM(poly_evenOdd)
    MAKE_GM(poly_clockwise)
    MAKE_GM(preserverendertarget)
    MAKE_GM(preserverendertarget_empty)
    MAKE_GM(rawtext)
    MAKE_GM(rect)
    MAKE_GM(rect_grad)
    MAKE_GM(retrofittedcubictriangles)
    MAKE_GM(roundjoinstrokes)
    MAKE_GM(strokedlines)
    MAKE_GM(strokefill)
    MAKE_GM(bug339297)
    MAKE_GM(bug339297_as_clip)
    MAKE_GM(bug6987)
    MAKE_GM(strokes_round)
    MAKE_GM(strokes_poly)
    MAKE_GM(strokes3)
    MAKE_GM(strokes_zoomed)
    MAKE_GM(zero_control_stroke)
    MAKE_GM(zeroPath)
    MAKE_GM(teenyStrokes)
    MAKE_GM(CubicStroke)
    MAKE_GM(zerolinestroke)
    MAKE_GM(quadcap)
    MAKE_GM(inner_join_geometry)
    MAKE_GM(skbug12244)
    MAKE_GM(offscreen_render_target)
    MAKE_GM(offscreen_render_target_nonrenderable)
    MAKE_GM(offscreen_render_target_preserve)
    MAKE_GM(offscreen_render_target_preserve_nonrenderable)
    MAKE_GM(transparentclear)
    MAKE_GM(verycomplexgrad)
    MAKE_GM(widebuttcaps)
    MAKE_GM(xfermodes2)
    MAKE_GM(trickycubicstrokes_roundcaps)
    MAKE_GM(emptyfeather)
    MAKE_GM(largeclippedpath_evenodd_nested)
    MAKE_GM(feather_polyshapes)
    MAKE_GM(largeclippedpath_clockwise)
    MAKE_GM(largeclippedpath_winding)
    MAKE_GM(largeclippedpath_evenodd)
    MAKE_GM(transparentclear_blendmode)
    MAKE_GM(emptystrokefeather)
    MAKE_GM(emptystroke)
    MAKE_GM(trickycubicstrokes)
    MAKE_GM(offscreen_render_target_preserve_lum)
    MAKE_GM(offscreen_render_target_preserve_lum_nonrenderable)
    MAKE_GM(preserverendertarget_blendmode)
    MAKE_GM(largeclippedpath_winding_nested)
    MAKE_GM(largeclippedpath_clockwise_nested)
    MAKE_GM(trickycubicstrokes_feather)
}

static void dump_gm(GM* gm, const std::string& name)
{
    uint32_t width = gm->width();
    uint32_t height = gm->height();
    TestingWindow::Get()->resize(width, height);
    std::vector<uint8_t> pixels;
    if (verbose)
    {
        printf("[gms] Running %s...\n", name.c_str());
    }
    gm->run(&pixels);
    assert(pixels.size() == height * width * 4);
    if (TestHarness::Instance().initialized())
    {
        TestHarness::Instance().savePNG({
            .name = name,
            .width = width,
            .height = height,
            .pixels = std::move(pixels),
        });
    }
    if (verbose)
    {
        printf("[gms] Sent %s.png\n", name.c_str());
    }
}

static bool contains(const std::string& str, const std::string& substr)
{
    auto pos = str.find(substr, 0);
    return pos < str.size();
}

static void dumpGMs(const std::string& match, bool interactive)
{

    for (const auto& [make_gm, name] : gmRegistry)
    {
        std::unique_ptr<GM> gm(make_gm());

        if (!gm)
        {
            continue;
        }
        if (match.size() && !contains(name, match))
        {
            continue; // This gm got filtered out by the '--match' argument.
        }
        if (!TestHarness::Instance().claimGMTest(name))
        {
            continue; // A different process already drew this gm.
        }
        gm->onceBeforeDraw();

        dump_gm(gm.get(), name);
        if (interactive)
        {
            // Wait for any key if in interactive mode.
            TestingWindow::InputEventData inputEventData =
                TestingWindow::Get()->waitForInputEvent();
            // Anything that isn't a key press will not progress.
            while (inputEventData.eventType !=
                   TestingWindow::InputEvent::KeyPress)
            {
                inputEventData = TestingWindow::Get()->waitForInputEvent();
            }
        }
#ifdef RIVE_ANDROID
        if (!rive_android_app_poll_once())
        {
            return;
        }
#endif
    }
}

static bool is_arg(const char arg[],
                   const char target[],
                   const char alt[] = nullptr)
{
    return !strcmp(arg, target) || (arg && !strcmp(arg, alt));
}

#if defined(RIVE_UNREAL)

extern "C" REGISTRY_HANDLE gms_get_registry_head() { return 0; }

extern "C" REGISTRY_HANDLE gms_registry_get_next(
    REGISTRY_HANDLE position_handle)
{
    assert(position_handle >= 0);
    if (position_handle == gmRegistry.size() - 1)
        return INVALID_REGISTRY;
    return position_handle + 1;
}

extern "C" bool gms_run_gm(REGISTRY_HANDLE position_handle)
{
    assert(position_handle >= 0);
    assert(position_handle < gmRegistry.size());
    const auto& [make_gm, gmName] = gmRegistry[position_handle];

    std::unique_ptr<GM> gm(make_gm());

    if (!gm)
    {
        return false;
    }

    gm->onceBeforeDraw();

    uint32_t width = gm->width();
    uint32_t height = gm->height();
    TestingWindow::Get()->resize(width, height);
    gm->run(nullptr);

    return true;
}

extern "C" bool gms_registry_get_name(REGISTRY_HANDLE position_handle,
                                      std::string& name)
{
    assert(position_handle >= 0);
    assert(position_handle < gmRegistry.size());
    const auto& [make_gm, gmName] = gmRegistry[position_handle];

    name = gmName;
    return true;
}

extern "C" bool gms_registry_get_size(REGISTRY_HANDLE position_handle,
                                      size_t& width,
                                      size_t& height)
{
    assert(position_handle >= 0);
    assert(position_handle < gmRegistry.size());
    const auto& [make_gm, gmName] = gmRegistry[position_handle];

    std::unique_ptr<GM> gm(make_gm());

    width = 0;
    height = 0;

    if (!gm)
    {
        return false;
    }

    width = gm->width();
    height = gm->height();

    return true;
}

extern "C" int gms_main(int argc, const char* argv[])
#elif defined(RIVE_IOS) || defined(RIVE_IOS_SIMULATOR)
int gms_ios_main(int argc, const char* argv[])
#elif defined(RIVE_ANDROID)
int rive_android_main(int argc, const char* const* argv)
#else
int main(int argc, const char* argv[])
#endif
{
#ifdef _WIN32
    // Cause stdout and stderr to print immediately without buffering.
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);
#endif

    const char* match = "";
    bool interactive = false;
    auto backend = TestingWindow::Backend::gl;
    TestingWindow::BackendParams backendParams;
    auto visibility = TestingWindow::Visibility::window;
    int pngThreads = 2;

    for (int i = 1; i < argc; ++i)
    {
        if (strcmp(argv[i], "--test_harness") == 0)
        {
            TestHarness::Instance().init(TCPClient::Connect(argv[++i]),
                                         pngThreads);
            continue;
        }
        if (is_arg(argv[i], "--output", "-o"))
        {
            TestHarness::Instance().init(std::filesystem::path(argv[++i]),
                                         pngThreads);
            continue;
        }
        if (is_arg(argv[i], "--match", "-m"))
        {
            match = argv[++i];
            continue;
        }
        if (is_arg(argv[i], "--fast-png", "-f"))
        {
            TestHarness::Instance().setPNGCompression(PNGCompression::fast_rle);
            continue;
        }
        if (is_arg(argv[i], "--interactive", "-i"))
        {
            interactive = true;
            continue;
        }
        if (is_arg(argv[i], "--backend", "-b"))
        {
            backend = TestingWindow::ParseBackend(argv[++i], &backendParams);
            continue;
        }
        if (is_arg(argv[i], "--headless", "-d"))
        {
            visibility = TestingWindow::Visibility::headless;
            continue;
        }
        if (is_arg(argv[i], "--verbose", "-v"))
        {
            verbose = true;
            continue;
        }
        if (sscanf(argv[i], "-p%d", &pngThreads) == 1)
        {
            pngThreads = std::max(pngThreads, 1);
            continue;
        }
        printf("Unrecognized argument %s\n", argv[i]);
        return 1;
    }

    void* platformWindow = nullptr;
#ifdef RIVE_ANDROID
    // Make sure the testing harness always gets initialized on Android so we
    // pipe stdout & stderr to the android log always get pngs.
    if (!TestHarness::Instance().initialized())
    {
        // Android introduced a lot of changes to external storage at v11. We
        // need to dump the pngs to different locations pre and post 11.
        char androidOSVersion[PROP_VALUE_MAX + 1] = {0};
        __system_property_get("ro.build.version.release", androidOSVersion);
        int androidOSVersionMajor = atoi(androidOSVersion);
        const char* pngLocation =
            androidOSVersionMajor >= 11
                ? "/sdcard/Pictures/rive_gms"
                : "/sdcard/Android/data/app.rive.android_tests/files/data/gms";
        TestHarness::Instance().init(std::filesystem::path(pngLocation), 4);
        // When the app is launched with no test harness, presumably via tap or
        // some other automation process, always do verbose output.
        verbose = true;
    }
    // Render directly to the main window to give feedback.
    platformWindow = rive_android_app_wait_for_window();
    if (platformWindow != nullptr)
    {
        visibility = TestingWindow::Visibility::fullscreen;
    }
#endif
    TestingWindow::Init(backend, backendParams, visibility, platformWindow);
#ifndef RIVE_UNREAL // unreal calls this directly instead
    gms_build_registry();
#endif

    dumpGMs(std::string(match), interactive);

    gmRegistry.clear();
    TestingWindow::Destroy(); // Exercise our PLS teardown process now that
                              // we're done.
    TestHarness::Instance().shutdown();
    return 0;
}

#endif
