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

#include "include/core/SkRefCnt.h"
#include "include/core/SkSpan.h"
#include "include/core/SkString.h"
#include "include/private/SkTArray.h"
#include "src/core/SkTInternalLList.h"
#include "src/gpu/ganesh/GrRenderTask.h"
#include "src/gpu/ganesh/GrRenderTaskCluster.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/gpu/ganesh/mock/GrMockRenderTask.h"
#include "src/gpu/ganesh/mock/GrMockSurfaceProxy.h"
#include "tests/Test.h"

#include <array>
#include <cstddef>
#include <utility>

typedef void (*CreateGraphPF)(SkTArray<sk_sp<GrMockRenderTask>>* graph,
                              SkTArray<sk_sp<GrMockRenderTask>>* expected);

static void make_proxies(int count, SkTArray<sk_sp<GrSurfaceProxy>>* proxies) {
    proxies->reset(count);
    for (int i = 0; i < count; i++) {
        auto name = SkStringPrintf("%c", 'A' + i);
        proxies->at(i) = sk_make_sp<GrMockSurfaceProxy>(std::move(name),
        /*label=*/"RenderTaskClusterTest");
    }
}

static void make_tasks(int count, SkTArray<sk_sp<GrMockRenderTask>>* tasks) {
    tasks->reset(count);
    for (int i = 0; i < count; i++) {
        tasks->at(i) = sk_make_sp<GrMockRenderTask>();
    }
}

/*
 * In:  A1 B1 A2
 * Out: B1 A1 A2
 */
static void create_graph0(SkTArray<sk_sp<GrMockRenderTask>>* graph,
                          SkTArray<sk_sp<GrMockRenderTask>>* expected) {
    SkTArray<sk_sp<GrSurfaceProxy>> proxies;
    make_proxies(2, &proxies);
    make_tasks(3, graph);

    graph->at(0)->addTarget(proxies[0]);
    graph->at(1)->addTarget(proxies[1]);
    graph->at(2)->addTarget(proxies[0]);
    graph->at(2)->addDependency(graph->at(1).get());

    expected->push_back(graph->at(1));
    expected->push_back(graph->at(0));
    expected->push_back(graph->at(2));
}

/*
 * In:  A1 B1 A2 C1 A3
 * Out: B1 C1 A1 A2 A3
 */
static void create_graph1(SkTArray<sk_sp<GrMockRenderTask>>* graph,
                          SkTArray<sk_sp<GrMockRenderTask>>* expected) {
    SkTArray<sk_sp<GrSurfaceProxy>> proxies;
    make_proxies(3, &proxies);
    make_tasks(5, graph);

    graph->at(0)->addTarget(proxies[0]);
    graph->at(1)->addTarget(proxies[1]);
    graph->at(2)->addTarget(proxies[0]);
    graph->at(3)->addTarget(proxies[2]);
    graph->at(4)->addTarget(proxies[0]);

    expected->push_back(graph->at(1));
    expected->push_back(graph->at(3));
    expected->push_back(graph->at(0));
    expected->push_back(graph->at(2));
    expected->push_back(graph->at(4));
}

/*
 * In:   A1 B1 A2.
 * Srcs: A1->B1, B1->A2.
 * Out:  A1 B1 A2. Can't reorder.
 */
static void create_graph2(SkTArray<sk_sp<GrMockRenderTask>>* graph,
                          SkTArray<sk_sp<GrMockRenderTask>>* expected) {
    SkTArray<sk_sp<GrSurfaceProxy>> proxies;
    make_proxies(2, &proxies);
    make_tasks(3, graph);

    graph->at(0)->addTarget(proxies[0]);
    graph->at(1)->addTarget(proxies[1]);
    graph->at(2)->addTarget(proxies[0]);

    graph->at(1)->addDependency(graph->at(0).get());
    graph->at(2)->addDependency(graph->at(1).get());

    // expected is empty. Can't reorder.
}

/*
 * Write-after-read case.
 * In:   A1 B1 A2 B2
 * Srcs: A1->B1, A2->B2
 * Used: B1(A), B2(A)
 * Out:  Can't reorder.
 */
static void create_graph3(SkTArray<sk_sp<GrMockRenderTask>>* graph,
                          SkTArray<sk_sp<GrMockRenderTask>>* expected) {
    SkTArray<sk_sp<GrSurfaceProxy>> proxies;
    make_proxies(2, &proxies);
    make_tasks(4, graph);

    graph->at(0)->addTarget(proxies[0]);
    graph->at(1)->addTarget(proxies[1]);
    graph->at(2)->addTarget(proxies[0]);
    graph->at(3)->addTarget(proxies[1]);

    graph->at(1)->addDependency(graph->at(0).get());
    graph->at(3)->addDependency(graph->at(2).get());

    graph->at(1)->addUsed(proxies[0]);
    graph->at(3)->addUsed(proxies[0]);

    // expected is empty. Can't reorder.
}

DEF_TEST(GrRenderTaskCluster, reporter) {
    CreateGraphPF tests[] = {
        create_graph0,
        create_graph1,
        create_graph2,
        create_graph3
    };

    for (size_t i = 0; i < std::size(tests); ++i) {
        SkTArray<sk_sp<GrMockRenderTask>> graph;
        SkTArray<sk_sp<GrMockRenderTask>> expectedOutput;

        (tests[i])(&graph, &expectedOutput);

        SkTInternalLList<GrRenderTask> llist;
        // TODO: Why does Span not want to convert from sk_sp<GrMockRenderTask> to
        // `const sk_sp<GrRenderTask>`?
        SkSpan<const sk_sp<GrRenderTask>> graphSpan(
            reinterpret_cast<sk_sp<GrRenderTask>*>(graph.data()), graph.size());
        bool actualResult = GrClusterRenderTasks(graphSpan, &llist);

        if (expectedOutput.empty()) {
            REPORTER_ASSERT(reporter, !actualResult);
            size_t newCount = 0;
            for (const GrRenderTask* t : llist) {
                REPORTER_ASSERT(reporter, newCount < graphSpan.size() &&
                                          t == graph[newCount].get());
                ++newCount;
            }
            REPORTER_ASSERT(reporter, newCount == graphSpan.size());
        } else {
            REPORTER_ASSERT(reporter, actualResult);
            // SkTInternalLList::countEntries is debug-only and these tests run in release.
            int newCount = 0;
            for ([[maybe_unused]] GrRenderTask* t : llist) {
                newCount++;
            }
            REPORTER_ASSERT(reporter, newCount == expectedOutput.size());

            int j = 0;
            for (GrRenderTask* n : llist) {
                REPORTER_ASSERT(reporter, n == expectedOutput[j++].get());
            }
        }

        //SkDEBUGCODE(print(graph);)
    }
}
