/*
 * 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/SkPath.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRegion.h"
#include "include/utils/SkRandom.h"
#include "src/core/SkAutoMalloc.h"
#include "tests/Test.h"

static void Union(SkRegion* rgn, const SkIRect& rect) {
    rgn->op(rect, SkRegion::kUnion_Op);
}

#define TEST_NO_INTERSECT(rgn, rect)    REPORTER_ASSERT(reporter, !rgn.intersects(rect))
#define TEST_INTERSECT(rgn, rect)       REPORTER_ASSERT(reporter, rgn.intersects(rect))
#define TEST_NO_CONTAINS(rgn, rect)     REPORTER_ASSERT(reporter, !rgn.contains(rect))

// inspired by http://code.google.com/p/skia/issues/detail?id=958
//
static void test_fromchrome(skiatest::Reporter* reporter) {
    SkRegion r;
    Union(&r, SkIRect::MakeXYWH(0, 0, 1, 1));
    TEST_NO_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 0, 0));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 2, 2));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, 0, 2, 2));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 2, 2));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, -1, 2, 2));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 3, 3));

    Union(&r, SkIRect::MakeXYWH(0, 0, 3, 3));
    Union(&r, SkIRect::MakeXYWH(10, 0, 3, 3));
    Union(&r, SkIRect::MakeXYWH(0, 10, 13, 3));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 2, 2));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 2, 2));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 2, 2, 2));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, 2, 2, 2));

    TEST_INTERSECT(r, SkIRect::MakeXYWH(9, -1, 2, 2));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(12, -1, 2, 2));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(12, 2, 2, 2));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(9, 2, 2, 2));

    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, -1, 13, 5));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(1, -1, 11, 5));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 9, 5));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 8, 5));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(3, -1, 8, 5));

    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 1, 13, 1));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(1, 1, 11, 1));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 1, 9, 1));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 1, 8, 1));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(3, 1, 8, 1));

    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 13, 13));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 1, 13, 11));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 2, 13, 9));
    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 2, 13, 8));


    // These test SkRegion::contains(Rect) and SkRegion::contains(Region)

    SkRegion container;
    Union(&container, SkIRect::MakeXYWH(0, 0, 40, 20));
    Union(&container, SkIRect::MakeXYWH(30, 20, 10, 20));
    TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(0, 0, 10, 39));
    TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(29, 0, 10, 39));

    {
        SkRegion rgn;
        Union(&rgn, SkIRect::MakeXYWH(0, 0, 10, 10));
        Union(&rgn, SkIRect::MakeLTRB(5, 10, 20, 20));
        TEST_INTERSECT(rgn, SkIRect::MakeXYWH(15, 0, 5, 11));
    }
}

static void test_empties(skiatest::Reporter* reporter) {
    SkRegion valid(SkIRect::MakeWH(10, 10));
    SkRegion empty, empty2;

    REPORTER_ASSERT(reporter, empty.isEmpty());
    REPORTER_ASSERT(reporter, !valid.isEmpty());

    // test intersects
    REPORTER_ASSERT(reporter, !empty.intersects(empty2));
    REPORTER_ASSERT(reporter, !valid.intersects(empty));

    // test contains
    REPORTER_ASSERT(reporter, !empty.contains(empty2));
    REPORTER_ASSERT(reporter, !valid.contains(empty));
    REPORTER_ASSERT(reporter, !empty.contains(valid));

    SkPath emptyPath;
    emptyPath.moveTo(1, 5);
    emptyPath.close();
    SkRegion openClip;
    openClip.setRect({-16000, -16000, 16000, 16000});
    empty.setPath(emptyPath, openClip);  // should not assert
}

enum {
    W = 256,
    H = 256
};

static SkIRect randRect(SkRandom& rand) {
    int x = rand.nextU() % W;
    int y = rand.nextU() % H;
    int w = rand.nextU() % W;
    int h = rand.nextU() % H;
    return SkIRect::MakeXYWH(x, y, w >> 1, h >> 1);
}

static void randRgn(SkRandom& rand, SkRegion* rgn, int n) {
    rgn->setEmpty();
    for (int i = 0; i < n; ++i) {
        rgn->op(randRect(rand), SkRegion::kUnion_Op);
    }
}

static bool slow_contains(const SkRegion& outer, const SkRegion& inner) {
    SkRegion tmp;
    tmp.op(outer, inner, SkRegion::kUnion_Op);
    return outer == tmp;
}

static bool slow_contains(const SkRegion& outer, const SkIRect& r) {
    SkRegion tmp;
    tmp.op(outer, SkRegion(r), SkRegion::kUnion_Op);
    return outer == tmp;
}

static bool slow_intersects(const SkRegion& outer, const SkRegion& inner) {
    SkRegion tmp;
    return tmp.op(outer, inner, SkRegion::kIntersect_Op);
}

static void test_contains_iter(skiatest::Reporter* reporter, const SkRegion& rgn) {
    SkRegion::Iterator iter(rgn);
    while (!iter.done()) {
        SkIRect r = iter.rect();
        REPORTER_ASSERT(reporter, rgn.contains(r));
        r.inset(-1, -1);
        REPORTER_ASSERT(reporter, !rgn.contains(r));
        iter.next();
    }
}

static void contains_proc(skiatest::Reporter* reporter,
                          const SkRegion& a, const SkRegion& b) {
    // test rgn
    bool c0 = a.contains(b);
    bool c1 = slow_contains(a, b);
    REPORTER_ASSERT(reporter, c0 == c1);

    // test rect
    SkIRect r = a.getBounds();
    r.inset(r.width()/4, r.height()/4);
    c0 = a.contains(r);
    c1 = slow_contains(a, r);
    REPORTER_ASSERT(reporter, c0 == c1);

    test_contains_iter(reporter, a);
    test_contains_iter(reporter, b);
}

static void test_intersects_iter(skiatest::Reporter* reporter, const SkRegion& rgn) {
    SkRegion::Iterator iter(rgn);
    while (!iter.done()) {
        SkIRect r = iter.rect();
        REPORTER_ASSERT(reporter, rgn.intersects(r));
        r.inset(-1, -1);
        REPORTER_ASSERT(reporter, rgn.intersects(r));
        iter.next();
    }
}

static void intersects_proc(skiatest::Reporter* reporter,
                          const SkRegion& a, const SkRegion& b) {
    bool c0 = a.intersects(b);
    bool c1 = slow_intersects(a, b);
    REPORTER_ASSERT(reporter, c0 == c1);

    test_intersects_iter(reporter, a);
    test_intersects_iter(reporter, b);
}

static void test_proc(skiatest::Reporter* reporter,
                      void (*proc)(skiatest::Reporter*,
                                   const SkRegion& a, const SkRegion&)) {
    SkRandom rand;
    for (int i = 0; i < 10000; ++i) {
        SkRegion outer;
        randRgn(rand, &outer, 8);
        SkRegion inner;
        randRgn(rand, &inner, 2);
        proc(reporter, outer, inner);
    }
}

static void rand_rect(SkIRect* rect, SkRandom& rand) {
    int bits = 6;
    int shift = 32 - bits;
    rect->setLTRB(rand.nextU() >> shift, rand.nextU() >> shift,
                  rand.nextU() >> shift, rand.nextU() >> shift);
    rect->sort();
}

static bool test_rects(const SkIRect rect[], int count) {
    SkRegion rgn0, rgn1;

    for (int i = 0; i < count; i++) {
        rgn0.op(rect[i], SkRegion::kUnion_Op);
    }
    rgn1.setRects(rect, count);

    if (rgn0 != rgn1) {
        SkDebugf("\n");
        for (int i = 0; i < count; i++) {
            SkDebugf(" { %d, %d, %d, %d },\n",
                     rect[i].fLeft, rect[i].fTop,
                     rect[i].fRight, rect[i].fBottom);
        }
        SkDebugf("\n");
        return false;
    }
    return true;
}

DEF_TEST(Region, reporter) {
    const SkIRect r2[] = {
        { 0, 0, 1, 1 },
        { 2, 2, 3, 3 },
    };
    REPORTER_ASSERT(reporter, test_rects(r2, SK_ARRAY_COUNT(r2)));

    const SkIRect rects[] = {
        { 0, 0, 1, 2 },
        { 2, 1, 3, 3 },
        { 4, 0, 5, 1 },
        { 6, 0, 7, 4 },
    };
    REPORTER_ASSERT(reporter, test_rects(rects, SK_ARRAY_COUNT(rects)));

    SkRandom rand;
    for (int i = 0; i < 1000; i++) {
        SkRegion rgn0, rgn1;

        const int N = 8;
        SkIRect rect[N];
        for (int j = 0; j < N; j++) {
            rand_rect(&rect[j], rand);
        }
        REPORTER_ASSERT(reporter, test_rects(rect, N));
    }

    test_proc(reporter, contains_proc);
    test_proc(reporter, intersects_proc);
    test_empties(reporter);
    test_fromchrome(reporter);
}

// Test that writeToMemory reports the same number of bytes whether there was a
// buffer to write to or not.
static void test_write(const SkRegion& region, skiatest::Reporter* r) {
    const size_t bytesNeeded = region.writeToMemory(nullptr);
    SkAutoMalloc storage(bytesNeeded);
    const size_t bytesWritten = region.writeToMemory(storage.get());
    REPORTER_ASSERT(r, bytesWritten == bytesNeeded);

    // Also check that the bytes are meaningful.
    SkRegion copy;
    REPORTER_ASSERT(r, copy.readFromMemory(storage.get(), bytesNeeded));
    REPORTER_ASSERT(r, region == copy);
}

DEF_TEST(Region_writeToMemory, r) {
    // Test an empty region.
    SkRegion region;
    REPORTER_ASSERT(r, region.isEmpty());
    test_write(region, r);

    // Test a rectangular region
    bool nonEmpty = region.setRect({0, 0, 50, 50});
    REPORTER_ASSERT(r, nonEmpty);
    REPORTER_ASSERT(r, region.isRect());
    test_write(region, r);

    // Test a complex region
    nonEmpty = region.op({50, 50, 100, 100}, SkRegion::kUnion_Op);
    REPORTER_ASSERT(r, nonEmpty);
    REPORTER_ASSERT(r, region.isComplex());
    test_write(region, r);

    SkRegion complexRegion;
    Union(&complexRegion, SkIRect::MakeXYWH(0, 0, 1, 1));
    Union(&complexRegion, SkIRect::MakeXYWH(0, 0, 3, 3));
    Union(&complexRegion, SkIRect::MakeXYWH(10, 0, 3, 3));
    Union(&complexRegion, SkIRect::MakeXYWH(0, 10, 13, 3));
    test_write(complexRegion, r);

    Union(&complexRegion, SkIRect::MakeXYWH(10, 20, 3, 3));
    Union(&complexRegion, SkIRect::MakeXYWH(0,  20, 3, 3));
    test_write(complexRegion, r);
}

DEF_TEST(Region_readFromMemory_bad, r) {
    // These assume what our binary format is: conceivably we could change it
    // and might need to remove or change some of these tests.
    SkRegion region;

    {
        // invalid boundary rectangle
        int32_t data[5] = {0, 4, 4, 8, 2};
        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
    }
    // Region Layout, Serialized Format:
    //    COUNT LEFT TOP RIGHT BOTTOM Y_SPAN_COUNT TOTAL_INTERVAL_COUNT
    //    Top ( Bottom Span_Interval_Count ( Left Right )* Sentinel )+ Sentinel
    {
        // Example of valid data
        int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
                          2147483647, 2147483647};
        REPORTER_ASSERT(r, 0 != region.readFromMemory(data, sizeof(data)));
    }
    {
        // Example of valid data with 4 intervals
        int32_t data[] = {19, 0, 0, 30, 30, 3, 4, 0, 10, 2, 0, 10, 20, 30,
                          2147483647, 20, 0, 2147483647, 30, 2, 0, 10, 20, 30,
                          2147483647, 2147483647};
        REPORTER_ASSERT(r, 0 != region.readFromMemory(data, sizeof(data)));
    }
    {
        // Short count
        int32_t data[] = {8, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
                          2147483647, 2147483647};
        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
    }
    {
        // bounds don't match
        int32_t data[] = {9, 0, 0, 10, 11, 1, 2, 0, 10, 2, 0, 4, 6, 10,
                          2147483647, 2147483647};
        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
    }
    {
        //  bad yspan count
        int32_t data[] = {9, 0, 0, 10, 10, 2, 2, 0, 10, 2, 0, 4, 6, 10,
                          2147483647, 2147483647};
        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
    }
    {
        // bad int count
        int32_t data[] = {9, 0, 0, 10, 10, 1, 3, 0, 10, 2, 0, 4, 6, 10,
                          2147483647, 2147483647};
        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
    }
    {
        // bad final sentinal
        int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
                          2147483647, -1};
        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
    }
    {
        // bad row sentinal
        int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
                          -1, 2147483647};
        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
    }
    {
        // starts with empty yspan
        int32_t data[] = {12, 0, 0, 10, 10, 2, 2, -5, 0, 0, 2147483647, 10,
                          2, 0, 4, 6, 10, 2147483647, 2147483647};
        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
    }
    {
        // ends with empty yspan
        int32_t data[] = {12, 0, 0, 10, 10, 2, 2, 0, 10, 2, 0, 4, 6, 10,
                          2147483647, 15, 0, 2147483647, 2147483647};
        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
    }
    {
        // y intervals out of order
        int32_t data[] = {19, 0, -20, 30, 10, 3, 4, 0, 10, 2, 0, 10, 20, 30,
                          2147483647, -20, 0, 2147483647, -10, 2, 0, 10, 20, 30,
                          2147483647, 2147483647};
        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
    }
    {
        // x intervals out of order
        int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 6, 10, 0, 4,
                          2147483647, 2147483647};
        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
    }
}

DEF_TEST(region_toobig, reporter) {
    const int big = 1 << 30;
    const SkIRect neg = SkIRect::MakeXYWH(-big, -big, 10, 10);
    const SkIRect pos = SkIRect::MakeXYWH( big,  big, 10, 10);

    REPORTER_ASSERT(reporter, !neg.isEmpty());
    REPORTER_ASSERT(reporter, !pos.isEmpty());

    SkRegion negR(neg);
    SkRegion posR(pos);

    REPORTER_ASSERT(reporter, !negR.isEmpty());
    REPORTER_ASSERT(reporter, !posR.isEmpty());

    SkRegion rgn;
    rgn.op(negR, posR, SkRegion::kUnion_Op);

    // If we union those to rectangles, the resulting coordinates span more than int32_t, so
    // we must mark the region as empty.
    REPORTER_ASSERT(reporter, rgn.isEmpty());
}

DEF_TEST(region_inverse_union_skbug_7491, reporter) {
    SkPath path;
    path.setFillType(SkPathFillType::kInverseWinding);
    path.moveTo(10, 20); path.lineTo(10, 30); path.lineTo(10.1f, 10); path.close();

    SkRegion clip;
    clip.op(SkIRect::MakeLTRB(10, 10, 15, 20), SkRegion::kUnion_Op);
    clip.op(SkIRect::MakeLTRB(20, 10, 25, 20), SkRegion::kUnion_Op);

    SkRegion rgn;
    rgn.setPath(path, clip);

    REPORTER_ASSERT(reporter, clip == rgn);
}

DEF_TEST(giant_path_region, reporter) {
    const SkScalar big = 32767;
    SkPath path;
    path.moveTo(-big, 0);
    path.quadTo(big, 0, big, big);
    SkIRect ir = path.getBounds().round();
    SkRegion rgn;
    rgn.setPath(path, SkRegion(ir));
}

DEF_TEST(rrect_region_crbug_850350, reporter) {
    SkMatrix m;
    m.reset();
    m[1] = 0.753662348f;
    m[3] = 1.40079998E+20f;

    const SkPoint corners[] = {
        { 2.65876e-19f, 0.0194088f },
        { 4896, 0.00114702f },
        { 0, 0 },
        { 0.00114702f, 0.00495333f },
    };
    SkRRect rrect;
    rrect.setRectRadii({-8.72387e-31f, 1.29996e-38f, 4896, 1.125f}, corners);

    SkPath path;
    path.addRRect(rrect);
    path.transform(m);

    SkRegion rgn;
    rgn.setPath(path, SkRegion{SkIRect{0, 0, 24, 24}});
}

DEF_TEST(region_bug_chromium_873051, reporter) {
    SkRegion region;
    REPORTER_ASSERT(reporter,  region.setRect({0, 0, 0x7FFFFFFE, 0x7FFFFFFE}));
    REPORTER_ASSERT(reporter, !region.setRect({0, 0, 0x7FFFFFFE, 0x7FFFFFFF}));
    REPORTER_ASSERT(reporter, !region.setRect({0, 0, 0x7FFFFFFF, 0x7FFFFFFE}));
    REPORTER_ASSERT(reporter, !region.setRect({0, 0, 0x7FFFFFFF, 0x7FFFFFFF}));
}

DEF_TEST(region_empty_iter, reporter) {
    SkRegion::Iterator emptyIter;
    REPORTER_ASSERT(reporter, !emptyIter.rewind());
    REPORTER_ASSERT(reporter, emptyIter.done());
    auto eRect = emptyIter.rect();
    REPORTER_ASSERT(reporter, eRect.isEmpty());
    REPORTER_ASSERT(reporter, SkIRect::MakeEmpty() == eRect);
    REPORTER_ASSERT(reporter, !emptyIter.rgn());

    SkRegion region;
    SkRegion::Iterator resetIter;
    resetIter.reset(region);
    REPORTER_ASSERT(reporter, resetIter.rewind());
    REPORTER_ASSERT(reporter, resetIter.done());
    auto rRect = resetIter.rect();
    REPORTER_ASSERT(reporter, rRect.isEmpty());
    REPORTER_ASSERT(reporter, SkIRect::MakeEmpty() == rRect);
    REPORTER_ASSERT(reporter, resetIter.rgn());
    REPORTER_ASSERT(reporter, resetIter.rgn()->isEmpty());

    SkRegion::Iterator iter(region);
    REPORTER_ASSERT(reporter, iter.done());
    auto iRect = iter.rect();
    REPORTER_ASSERT(reporter, iRect.isEmpty());
    REPORTER_ASSERT(reporter, SkIRect::MakeEmpty() == iRect);
    REPORTER_ASSERT(reporter, iter.rgn());
    REPORTER_ASSERT(reporter, iter.rgn()->isEmpty());

    SkRegion::Cliperator clipIter(region, {0, 0, 100, 100});
    REPORTER_ASSERT(reporter, clipIter.done());
    auto cRect = clipIter.rect();
    REPORTER_ASSERT(reporter, cRect.isEmpty());
    REPORTER_ASSERT(reporter, SkIRect::MakeEmpty() == cRect);

    SkRegion::Spanerator spanIter(region, 0, 0, 100);
    int left = 0, right = 0;
    REPORTER_ASSERT(reporter, !spanIter.next(&left, &right));
    REPORTER_ASSERT(reporter, !left);
    REPORTER_ASSERT(reporter, !right);
}
