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


#include "include/core/SkColorType.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkString.h"
#include "src/core/SkTraceEvent.h"
#include "tests/Test.h"
#include "tools/flags/CommandLineFlags.h"

#include <cstdint>

#if !defined(SK_DISABLE_TRACING)

static DEFINE_bool(slowTracingTest, false,
                   "Artificially slow down tracing test to produce nicer JSON");

namespace {

/**
 * Helper types for demonstrating usage of TRACE_EVENT_OBJECT_XXX macros.
 */
struct TracingShape {
    TracingShape() {
        TRACE_EVENT_OBJECT_CREATED_WITH_ID("skia.objects", this->typeName(), this);
    }
    virtual ~TracingShape() {
        TRACE_EVENT_OBJECT_DELETED_WITH_ID("skia.objects", this->typeName(), this);
    }
    void traceSnapshot() {
        // The state of an object can be specified at any point with the OBJECT_SNAPSHOT macro.
        // This takes the "name" (actually the type name), the ID of the object (typically a
        // pointer), and a single (unnnamed) argument, which is the "snapshot" of that object.
        //
        // Tracing viewer requires that all object macros use the same name and id for creation,
        // deletion, and snapshots. However: It's convenient to put creation and deletion in the
        // base-class constructor/destructor where the actual type name isn't known yet. That's
        // what we're doing here. The JSON for snapshots can therefore include the actual type
        // name, and a special tag that refers to the type name originally used at creation time.
        // Skia's JSON tracer handles this automatically, so SNAPSHOT macros can simply use the
        // derived type name, and the JSON will be formatted correctly to link the events.
        TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID("skia.objects", this->typeName(), this,
                                            TRACE_STR_COPY(this->toString().c_str()));
    }

    virtual const char* typeName() { return "TracingShape"; }
    virtual SkString toString() { return SkString("Shape()"); }
};

struct TracingCircle : public TracingShape {
    TracingCircle(SkPoint center, SkScalar radius) : fCenter(center), fRadius(radius) {}
    const char* typeName() override { return "TracingCircle"; }
    SkString toString() override {
        return SkStringPrintf("Circle(%f, %f, %f)", fCenter.fX, fCenter.fY, fRadius);
    }
#if defined(SK_ANDROID_FRAMEWORK_USE_PERFETTO)
    void WriteIntoTrace(::perfetto::TracedValue context) {
        std::move(context).WriteString(toString().c_str());
    }
#endif

    SkPoint fCenter;
    SkScalar fRadius;
};

struct TracingRect : public TracingShape {
    TracingRect(SkRect rect) : fRect(rect) {}
    const char* typeName() override { return "TracingRect"; }
    SkString toString() override {
        return SkStringPrintf("Rect(%f, %f, %f, %f)",
                              fRect.fLeft, fRect.fTop, fRect.fRight, fRect.fBottom);
    }

    SkRect fRect;
};

}  // namespace

[[maybe_unused]]
static SkScalar gTracingTestWorkSink = 1.0f;

static void do_work(int howMuchWork) {
    // Do busy work so the trace marker durations are large enough to be readable in trace viewer
    if (FLAGS_slowTracingTest) {
        for (int i = 0; i < howMuchWork * 100; ++i) {
            gTracingTestWorkSink += SkScalarSin(i);
        }
    }
}

static void test_trace_simple() {
    // Simple event that lasts until the end of the current scope. TRACE_FUNC is an easy way
    // to insert the current function name.
    TRACE_EVENT0("skia", TRACE_FUNC);

    {
        // There are versions of the macro that take 1 or 2 named arguments. The arguments
        // can be any simple type. Strings need to be static/literal - we just copy pointers.
        // Argument names & values are shown when the event is selected in the viewer.
        TRACE_EVENT1("skia", "Nested work",
                     "isBGRA", kN32_SkColorType == kBGRA_8888_SkColorType);
        do_work(500);
    }

    {
        // If you must copy a string as an argument value, use the TRACE_STR_COPY macro.
        // This will instruct the tracing system (if one is active) to make a copy.
        SkString message = SkStringPrintf("%s %s", "Hello", "World");
        TRACE_EVENT1("skia", "Dynamic String", "message", TRACE_STR_COPY(message.c_str()));
        do_work(500);
    }
}

static void test_trace_counters() {
    TRACE_EVENT0("skia", TRACE_FUNC);

    {
        TRACE_EVENT0("skia", "Single Counter");

        // Counter macros allow recording a named value (which must be a 32-bit integer).
        // The value will be graphed in the viewer.
        for (int i = 0; i < 180; ++i) {
            SkScalar rad = SkDegreesToRadians(SkIntToScalar(i));
            TRACE_COUNTER1("skia", "sin", SkScalarSin(rad) * 1000.0f + 1000.0f);
            do_work(10);
        }
    }

    {
        TRACE_EVENT0("skia", "Independent Counters");

        // Recording multiple counters with separate COUNTER1 macros will make separate graphs.
        for (int i = 0; i < 180; ++i) {
            SkScalar rad = SkDegreesToRadians(SkIntToScalar(i));
            TRACE_COUNTER1("skia", "sin", SkScalarSin(rad) * 1000.0f + 1000.0f);
            TRACE_COUNTER1("skia", "cos", SkScalarCos(rad) * 1000.0f + 1000.0f);
            do_work(10);
        }
    }

    {
        TRACE_EVENT0("skia", "Stacked Counters");

        // Two counters can be recorded together with COUNTER2. They will be graphed together,
        // as a stacked bar graph. The combined graph needs a name, as does each data series.
        for (int i = 0; i < 180; ++i) {
            SkScalar rad = SkDegreesToRadians(SkIntToScalar(i));
            TRACE_COUNTER2("skia", "trig",
                           "sin", SkScalarSin(rad) * 1000.0f + 1000.0f,
                           "cos", SkScalarCos(rad) * 1000.0f + 1000.0f);
            do_work(10);
        }
    }
}

static void test_trace_objects() {
    TRACE_EVENT0("skia", TRACE_FUNC);

    // Objects can be tracked through time with the TRACE_EVENT_OBJECT_ macros.
    // The macros in use (and their idiosyncracies) are commented in the TracingShape class above.

    TracingCircle* circle = new TracingCircle(SkPoint::Make(20, 20), 15);
    circle->traceSnapshot();
    do_work(100);

    // Make another object. Objects with the same base type are shown in the same row in the viewer.
    TracingRect* rect = new TracingRect(SkRect::MakeWH(100, 50));
    rect->traceSnapshot();
    do_work(100);

    // We can create multiple snapshots of objects to reflect their state over time.
    circle->fCenter.offset(10, 10);
    circle->traceSnapshot();

    {
        // Other events (duration or instant) can refer directly to objects. For Skia's JSON
        // tracer, having an argument whose name starts with '#' will trigger the creation of JSON
        // that links the event to the object (with a direct link to the most recent snapshot).
        TRACE_EVENT1("skia", "Processing Shape", "#shape", circle);
        do_work(100);
    }

    delete circle;
    delete rect;
}

DEF_TEST(Tracing, reporter) {
    test_trace_simple();
    test_trace_counters();
    test_trace_objects();
}

#endif // SK_DISABLE_TRACING
