/*
 * Copyright 2014 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/SkCanvas.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkPathUtils.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkStrokeRec.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkDashPathEffect.h"
#include "src/core/SkPathEffectBase.h"
#include "tests/Test.h"

#include <array>

// crbug.com/348821 was rooted in SkDashPathEffect refusing to flatten and unflatten itself when
// the effect is nonsense.  Here we test that it fails when passed nonsense parameters.

DEF_TEST(DashPathEffectTest_crbug_348821, r) {
    SkScalar intervals[] = { 1.76934361e+36f, 2.80259693e-45f };  // Values from bug.
    SkScalar phase = SK_ScalarInfinity;  // Used to force a nonsense effect.
    sk_sp<SkPathEffect> dash(SkDashPathEffect::Make(intervals, phase));

    REPORTER_ASSERT(r, dash == nullptr);
}

// Test out the asPoint culling behavior.
DEF_TEST(DashPathEffectTest_asPoints, r) {

    const SkScalar intervals[] = { 1.0f, 1.0f };
    sk_sp<SkPathEffect> dash(SkDashPathEffect::Make(intervals, 0.0f));

    SkRect cull = SkRect::MakeWH(1.0f, 1.0f);

    struct TestCases {
        SkPoint fPts[2];
        bool    fExpectedResult;
    };

    using TC = TestCases;
    static constexpr auto testCases = std::to_array<TestCases>({
        TC{ { { -5.0f,  0.5f }, { -4.0f,  0.5f } }, false }, // off to the left
        TC{ { {  4.0f,  0.5f }, {  5.0f,  0.5f } }, false }, // off to the right
        TC{ { {  0.5f,  4.0f }, {  0.5f,  5.0f } }, false }, // off the bottom
        TC{ { {  0.5f, -5.0f }, {  0.5f, -4.0f } }, false }, // off the top
        TC{ { {  0.5f,  0.2f }, {  0.5f,  0.8f } }, true  }, // entirely inside vertical
        TC{ { {  0.2f,  0.5f }, {  0.8f,  0.5f } }, true  }, // entirely inside horizontal
        TC{ { {  0.5f, -5.0f }, {  0.5f,  5.0f } }, true  }, // straddles both sides vertically
        TC{ { { -5.0f,  0.5f }, {  5.0f,  0.5f } }, true  }, // straddles both sides horizontally
        TC{ { {  0.5f, -5.0f }, {  0.5f,  0.5f } }, true  }, // straddles top
        TC{ { {  0.5f,  5.0f }, {  0.5f,  0.5f } }, true  }, // straddles bottom
        TC{ { { -5.0f,  0.5f }, {  0.5f,  0.5f } }, true  }, // straddles left
        TC{ { {  5.0f,  0.5f }, {  0.5f,  0.5f } }, true  }, // straddles right
        TC{ { {  0.5f,  0.5f }, {  0.5f,  0.5f } }, false }, // zero length
    });

    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(1.0f);
    SkStrokeRec rec(paint);

    static const int kNumMats = 3;
    std::array<SkMatrix, kNumMats> mats;
    mats[0].reset();
    mats[1].setRotate(90, 0.5f, 0.5f);
    mats[2].setTranslate(10.0f, 10.0f);

    for (int i = 0; i < kNumMats; ++i) {
        for (int j = 0; j < (int)std::size(testCases); ++j) {
            for (int k = 0; k < 2; ++k) {  // exercise alternating endpoints
                SkPathEffectBase::PointData results;
                SkPath src = SkPath::Line(testCases[j].fPts[k],
                                          testCases[j].fPts[(k+1)%2]);

                bool actualResult = as_PEB(dash)->asPoints(&results, src, rec, mats[i], &cull);
                if (i < 2) {
                    REPORTER_ASSERT(r, actualResult == testCases[j].fExpectedResult);
                } else {
                    // On the third pass all the lines should be outside the translated cull rect
                    REPORTER_ASSERT(r, !actualResult);
                }
            }
        }
    }
}

DEF_TEST(DashPath_bug4871, r) {
    SkPath path = SkPathBuilder()
                  .moveTo(30, 24)
                  .cubicTo(30.002f, 24, 30, 24, 30, 24)
                  .close()
                  .detach();

    SkScalar intervals[2] = { 1, 1 };
    sk_sp<SkPathEffect> dash(SkDashPathEffect::Make(intervals, 0));

    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setPathEffect(dash);

    (void)skpathutils::FillPathWithPaint(path, paint);
}

// Verify that long lines with many dashes don't cause overflows/OOMs.
DEF_TEST(DashPathEffectTest_asPoints_limit, r) {
    sk_sp<SkSurface> surface(SkSurfaces::Raster(SkImageInfo::MakeN32Premul(256, 256)));
    SkCanvas* canvas = surface->getCanvas();

    SkPaint p;
    p.setStyle(SkPaint::kStroke_Style);
    // force the bounds to outset by a large amount
    p.setStrokeWidth(5.0e10f);
    const SkScalar intervals[] = { 1, 1 };
    p.setPathEffect(SkDashPathEffect::Make(intervals, 0));
    canvas->drawLine(1, 1, 1, 5.0e10f, p);
}

// This used to cause SkDashImpl to walk off the end of the intervals array, due to underflow
// trying to substract a smal value from a large one in floats.
DEF_TEST(DashCrazy_crbug_875494, r) {
    SkScalar vals[] = { 98, 94, 2888458849.f, 227, 0, 197 };

    SkRect cull = SkRect::MakeXYWH(43,236,57,149);
    SkPath path = SkPath::Rect(cull);

    SkPathBuilder builder;
    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setPathEffect(SkDashPathEffect::Make(vals, 222));
    skpathutils::FillPathWithPaint(path, paint, &builder, &cull, SkMatrix::I());
}

