/*
 * 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/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 (0) {
        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 (0) {
                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)
