/*
 * Copyright 2011 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/SkTypes.h"

#if !defined(SK_BUILD_FOR_GOOGLE3)

#include "include/core/SkRect.h"
#include "include/private/base/SkTo.h"
#include "modules/sksg/include/SkSGDraw.h"
#include "modules/sksg/include/SkSGGroup.h"
#include "modules/sksg/include/SkSGInvalidationController.h"
#include "modules/sksg/include/SkSGPaint.h"
#include "modules/sksg/include/SkSGRect.h"
#include "modules/sksg/include/SkSGRenderEffect.h"
#include "modules/sksg/include/SkSGTransform.h"
#include "src/core/SkRectPriv.h"

#include "tests/Test.h"

#include <vector>

static void check_inval(skiatest::Reporter* reporter, const sk_sp<sksg::Node>& root,
                        const SkRect& expected_bounds,
                        const SkRect& expected_inval_bounds,
                        const std::vector<SkRect>* expected_damage) {
    sksg::InvalidationController ic;
    const auto bbox = root->revalidate(&ic, SkMatrix::I());

    if ((false)) {
        SkDebugf("** bbox: [%f %f %f %f], ibbox: [%f %f %f %f]\n",
                 bbox.fLeft, bbox.fTop, bbox.fRight, bbox.fBottom,
                 ic.bounds().left(), ic.bounds().top(), ic.bounds().right(), ic.bounds().bottom());
    }

    REPORTER_ASSERT(reporter, bbox == expected_bounds);
    REPORTER_ASSERT(reporter, ic.bounds() == expected_inval_bounds);

    if (expected_damage) {
        const auto damage_count = SkTo<size_t>(ic.end() - ic.begin());
        REPORTER_ASSERT(reporter, expected_damage->size() == damage_count);
        for (size_t i = 0; i < std::min(expected_damage->size(), damage_count); ++i) {
            const auto r1 = (*expected_damage)[i],
                       r2 = ic.begin()[i];
            if ((false)) {
                SkDebugf("*** expected inval: [%f %f %f %f], actual: [%f %f %f %f]\n",
                         r1.left(), r1.top(), r1.right(), r1.bottom(),
                         r2.left(), r2.top(), r2.right(), r2.bottom());
            }
            REPORTER_ASSERT(reporter, r1 == r2);
        }
    }
}

struct HitTest {
    const SkPoint           pt;
    sk_sp<sksg::RenderNode> node;
};

static void check_hittest(skiatest::Reporter* reporter, const sk_sp<sksg::RenderNode>& root,
                          const std::vector<HitTest>& tests) {
    for (const auto& tst : tests) {
        const auto* node = root->nodeAt(tst.pt);
        if (node != tst.node.get()) {
            SkDebugf("*** nodeAt(%f, %f) - expected %p, got %p\n",
                     tst.pt.x(), tst.pt.y(), tst.node.get(), node);
        }
        REPORTER_ASSERT(reporter, tst.node.get() == node);
    }
}

static void inval_test1(skiatest::Reporter* reporter) {
    auto color  = sksg::Color::Make(0xff000000);
    auto r1     = sksg::Rect::Make(SkRect::MakeWH(100, 100)),
         r2     = sksg::Rect::Make(SkRect::MakeWH(100, 100));
    auto grp    = sksg::Group::Make();
    auto matrix = sksg::Matrix<SkMatrix>::Make(SkMatrix::I());
    auto root   = sksg::TransformEffect::Make(grp, matrix);
    auto d1     = sksg::Draw::Make(r1, color),
         d2     = sksg::Draw::Make(r2, color);

    grp->addChild(d1);
    grp->addChild(d2);

    {
        // Initial revalidation.
        check_inval(reporter, root,
                    SkRect::MakeWH(100, 100),
                    SkRectPriv::MakeLargeS32(),
                    nullptr);

        check_hittest(reporter, root, {
                          {{  -1,   0 }, nullptr },
                          {{   0,  -1 }, nullptr },
                          {{ 100,   0 }, nullptr },
                          {{   0, 100 }, nullptr },
                          {{   0,   0 },      d2 },
                          {{  99,  99 },      d2 },
                      });
    }

    {
        // Move r2 to (200 100).
        r2->setL(200); r2->setT(100); r2->setR(300); r2->setB(200);
        std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} };
        check_inval(reporter, root,
                    SkRect::MakeWH(300, 200),
                    SkRect::MakeWH(300, 200),
                    &damage);

        check_hittest(reporter, root, {
                          {{  -1,   0 }, nullptr },
                          {{   0,  -1 }, nullptr },
                          {{ 100,   0 }, nullptr },
                          {{   0, 100 }, nullptr },
                          {{   0,   0 },      d1 },
                          {{  99,  99 },      d1 },

                          {{ 199, 100 }, nullptr },
                          {{ 200,  99 }, nullptr },
                          {{ 300, 100 }, nullptr },
                          {{ 200, 200 }, nullptr },
                          {{ 200, 100 },      d2 },
                          {{ 299, 199 },      d2 },
                      });
    }

    {
        // Update the common color.
        color->setColor(0xffff0000);
        std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} };
        check_inval(reporter, root,
                    SkRect::MakeWH(300, 200),
                    SkRect::MakeWH(300, 200),
                    &damage);
    }

    {
        // Shrink r1.
        r1->setR(50);
        std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 50, 100} };
        check_inval(reporter, root,
                    SkRect::MakeWH(300, 200),
                    SkRect::MakeWH(100, 100),
                    &damage);

        check_hittest(reporter, root, {
                          {{  -1,   0 }, nullptr },
                          {{   0,  -1 }, nullptr },
                          {{  50,   0 }, nullptr },
                          {{   0, 100 }, nullptr },
                          {{   0,   0 },      d1 },
                          {{  49,  99 },      d1 },

                          {{ 199, 100 }, nullptr },
                          {{ 200,  99 }, nullptr },
                          {{ 300, 100 }, nullptr },
                          {{ 200, 200 }, nullptr },
                          {{ 200, 100 },      d2 },
                          {{ 299, 199 },      d2 },
                      });
    }

    {
        // Update transform.
        matrix->setMatrix(SkMatrix::Scale(2, 2));
        std::vector<SkRect> damage = { {0, 0, 300, 200}, { 0, 0, 600, 400} };
        check_inval(reporter, root,
                    SkRect::MakeWH(600, 400),
                    SkRect::MakeWH(600, 400),
                    &damage);

        check_hittest(reporter, root, {
                          {{  -1,   0 }, nullptr },
                          {{   0,  -1 }, nullptr },
                          {{  25,   0 }, nullptr },
                          {{   0,  50 }, nullptr },
                          {{   0,   0 },      d1 },
                          {{  24,  49 },      d1 },

                          {{  99,  50 }, nullptr },
                          {{ 100,  49 }, nullptr },
                          {{ 150,  50 }, nullptr },
                          {{ 100, 100 }, nullptr },
                          {{ 100,  50 },      d2 },
                          {{ 149,  99 },      d2 },
                      });
    }

    {
        // Shrink r2 under transform.
        r2->setR(250);
        std::vector<SkRect> damage = { {400, 200, 600, 400}, { 400, 200, 500, 400} };
        check_inval(reporter, root,
                    SkRect::MakeWH(500, 400),
                    SkRect::MakeLTRB(400, 200, 600, 400),
                    &damage);

        check_hittest(reporter, root, {
                          {{  -1,   0 }, nullptr },
                          {{   0,  -1 }, nullptr },
                          {{  25,   0 }, nullptr },
                          {{   0,  50 }, nullptr },
                          {{   0,   0 },      d1 },
                          {{  24,  49 },      d1 },

                          {{  99,  50 }, nullptr },
                          {{ 100,  49 }, nullptr },
                          {{ 125,  50 }, nullptr },
                          {{ 100, 100 }, nullptr },
                          {{ 100,  50 },      d2 },
                          {{ 124,  99 },      d2 },
                      });
    }
}

static void inval_test2(skiatest::Reporter* reporter) {
    auto color = sksg::Color::Make(0xff000000);
    auto rect  = sksg::Rect::Make(SkRect::MakeWH(100, 100));
    auto m1    = sksg::Matrix<SkMatrix>::Make(SkMatrix::I()),
         m2    = sksg::Matrix<SkMatrix>::Make(SkMatrix::I());
    auto t1    = sksg::TransformEffect::Make(sksg::Draw::Make(rect, color),
                                             sksg::Transform::MakeConcat(m1, m2)),
         t2    = sksg::TransformEffect::Make(sksg::Draw::Make(rect, color), m1);
    auto root  = sksg::Group::Make();
    root->addChild(t1);
    root->addChild(t2);

    {
        // Initial revalidation.
        check_inval(reporter, root,
                    SkRect::MakeWH(100, 100),
                    SkRectPriv::MakeLargeS32(),
                    nullptr);
    }

    {
        // Update the shared color.
        color->setColor(0xffff0000);
        std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 100, 100} };
        check_inval(reporter, root,
                    SkRect::MakeWH(100, 100),
                    SkRect::MakeWH(100, 100),
                    &damage);
    }

    {
        // Update m2.
        m2->setMatrix(SkMatrix::Scale(2, 2));
        std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 200, 200} };
        check_inval(reporter, root,
                    SkRect::MakeWH(200, 200),
                    SkRect::MakeWH(200, 200),
                    &damage);
    }

    {
        // Update shared m1.
        m1->setMatrix(SkMatrix::Translate(100, 100));
        std::vector<SkRect> damage = { {   0,   0, 200, 200},   // draw1 prev bounds
                                       { 100, 100, 300, 300},   // draw1 new bounds
                                       {   0,   0, 100, 100},   // draw2 prev bounds
                                       { 100, 100, 200, 200} }; // draw2 new bounds
        check_inval(reporter, root,
                    SkRect::MakeLTRB(100, 100, 300, 300),
                    SkRect::MakeLTRB(  0,   0, 300, 300),
                    &damage);
    }

    {
        // Update shared rect.
        rect->setR(50);
        std::vector<SkRect> damage = { { 100, 100, 300, 300},   // draw1 prev bounds
                                       { 100, 100, 200, 300},   // draw1 new bounds
                                       { 100, 100, 200, 200},   // draw2 prev bounds
                                       { 100, 100, 150, 200} }; // draw2 new bounds
        check_inval(reporter, root,
                    SkRect::MakeLTRB(100, 100, 200, 300),
                    SkRect::MakeLTRB(100, 100, 300, 300),
                    &damage);
    }
}

static void inval_test3(skiatest::Reporter* reporter) {
    auto color1 = sksg::Color::Make(0xff000000),
         color2 = sksg::Color::Make(0xff000000);
    auto group  = sksg::Group::Make();

    group->addChild(sksg::Draw::Make(sksg::Rect::Make(SkRect::MakeWH(100, 100)),
                                     color1));
    group->addChild(sksg::Draw::Make(sksg::Rect::Make(SkRect::MakeXYWH(200, 0, 100, 100)),
                                     color2));
    auto filter = sksg::DropShadowImageFilter::Make();
    filter->setOffset({50, 75});
    auto root = sksg::ImageFilterEffect::Make(group, filter);

    {
        // Initial revalidation.
        check_inval(reporter, root,
                    SkRect::MakeXYWH(0, 0, 350, 175),
                    SkRectPriv::MakeLargeS32(),
                    nullptr);
    }

    {
        // Shadow-only.
        filter->setMode(sksg::DropShadowImageFilter::Mode::kShadowOnly);
        std::vector<SkRect> damage = { {0, 0, 350, 175}, { 50, 75, 350, 175} };
        check_inval(reporter, root,
                    SkRect::MakeLTRB(50, 75, 350, 175),
                    SkRect::MakeLTRB(0, 0, 350, 175),
                    &damage);
    }

    {
        // Content change -> single/full filter bounds inval.
        color1->setColor(0xffff0000);
        std::vector<SkRect> damage = { { 50, 75, 350, 175} };
        check_inval(reporter, root,
                    SkRect::MakeLTRB(50, 75, 350, 175),
                    SkRect::MakeLTRB(50, 75, 350, 175),
                    &damage);
    }

    {
        // Visibility change -> full inval.
        group->setVisible(false);
        std::vector<SkRect> damage = { { 50, 75, 350, 175} };
        check_inval(reporter, root,
                    SkRect::MakeLTRB(50, 75, 350, 175),
                    SkRect::MakeLTRB(50, 75, 350, 175),
                    &damage);
    }
}

static void inval_group_remove(skiatest::Reporter* reporter) {
    auto draw = sksg::Draw::Make(sksg::Rect::Make(SkRect::MakeWH(100, 100)),
                                 sksg::Color::Make(SK_ColorBLACK));
    auto grp = sksg::Group::Make();

    // Readding the child should not trigger asserts.
    grp->addChild(draw);
    grp->removeChild(draw);
    grp->addChild(draw);
}

DEF_TEST(SGInvalidation, reporter) {
    inval_test1(reporter);
    inval_test2(reporter);
    inval_test3(reporter);
    inval_group_remove(reporter);
}

#endif // !defined(SK_BUILD_FOR_GOOGLE3)
