// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.


import 'dart:js_util' as js_util;
import 'dart:html' as html;
import 'dart:typed_data';
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/ui.dart' hide window;
import 'package:ui/src/engine.dart';

import 'matchers.dart';

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

void testMain() {
  group('Path', () {
    test('Should have no subpaths when created', () {
      final SurfacePath path = SurfacePath();
      expect(path.isEmpty, true);
    });

    test('LineTo should add command', () {
      final SurfacePath path = SurfacePath();
      path.moveTo(5.0, 10.0);
      path.lineTo(20.0, 40.0);
      path.lineTo(30.0, 50.0);
      expect(path.pathRef.countPoints(), 3);
      expect(path.pathRef.atPoint(2).dx, 30.0);
      expect(path.pathRef.atPoint(2).dy, 50.0);
    });

    test('LineTo should add moveTo 0,0 when first call to Path API', () {
      final SurfacePath path = SurfacePath();
      path.lineTo(20.0, 40.0);
      expect(path.pathRef.countPoints(), 2);
      expect(path.pathRef.atPoint(0).dx, 0);
      expect(path.pathRef.atPoint(0).dy, 0);
      expect(path.pathRef.atPoint(1).dx, 20.0);
      expect(path.pathRef.atPoint(1).dy, 40.0);
    });

    test('relativeLineTo should increments currentX', () {
      final SurfacePath path = SurfacePath();
      path.moveTo(5.0, 10.0);
      path.lineTo(20.0, 40.0);
      path.relativeLineTo(5.0, 5.0);
      expect(path.pathRef.countPoints(), 3);
      expect(path.pathRef.atPoint(2).dx, 25.0);
      expect(path.pathRef.atPoint(2).dy, 45.0);
    });

    test('Should allow calling relativeLineTo before moveTo', () {
      final SurfacePath path = SurfacePath();
      path.relativeLineTo(5.0, 5.0);
      path.moveTo(5.0, 10.0);
      expect(path.pathRef.countPoints(), 3);
      expect(path.pathRef.atPoint(1).dx, 5.0);
      expect(path.pathRef.atPoint(1).dy, 5.0);
      expect(path.pathRef.atPoint(2).dx, 5.0);
      expect(path.pathRef.atPoint(2).dy, 10.0);
    });

    test('Should allow relativeLineTo after reset', () {
      final SurfacePath path = SurfacePath();
      final Path subPath = Path();
      subPath.moveTo(50.0, 60.0);
      subPath.lineTo(200.0, 200.0);
      path.extendWithPath(subPath, const Offset(0.0, 0.0));
      path.reset();
      path.relativeLineTo(5.0, 5.0);
      expect(path.pathRef.countPoints(), 2);
      expect(path.pathRef.atPoint(0).dx, 0);
      expect(path.pathRef.atPoint(0).dy, 0);
      expect(path.pathRef.atPoint(1).dx, 5.0);
    });

    test('Should detect rectangular path', () {
      final SurfacePath path = SurfacePath();
      path.addRect(const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0));
      expect(path.toRect(), const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0));
    });

    test('Should detect horizontal line path', () {
      SurfacePath path = SurfacePath();
      path.moveTo(10, 20);
      path.lineTo(100, 0);
      expect(path.toStraightLine(), null);
      path = SurfacePath();
      path.moveTo(10, 20);
      path.lineTo(200, 20);
      Rect r = path.toStraightLine()!;
      expect(r, equals(Rect.fromLTRB(10, 20, 200, 20)));
    });

    test('Should detect vertical line path', () {
      final SurfacePath path = SurfacePath();
      path.moveTo(10, 20);
      path.lineTo(10, 200);
      Rect r = path.toStraightLine()!;
      expect(r, equals(Rect.fromLTRB(10, 20, 10, 200)));
    });

    test('Should detect non rectangular path if empty', () {
      final SurfacePath path = SurfacePath();
      expect(path.toRect(), null);
    });

    test('Should detect non rectangular path if there are multiple subpaths',
        () {
      final SurfacePath path = SurfacePath();
      path.addRect(const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0));
      path.addRect(const Rect.fromLTWH(5.0, 6.0, 7.0, 8.0));
      expect(path.toRect(), null);
    });

    test('Should detect rounded rectangular path', () {
      final SurfacePath path = SurfacePath();
      path.addRRect(RRect.fromRectAndRadius(
          const Rect.fromLTRB(1.0, 2.0, 30.0, 40.0),
          const Radius.circular(2.0)));
      expect(
          path.toRoundedRect(),
          RRect.fromRectAndRadius(const Rect.fromLTRB(1.0, 2.0, 30.0, 40.0),
              const Radius.circular(2.0)));
    });

    test('Should detect non rounded rectangular path if empty', () {
      final SurfacePath path = SurfacePath();
      expect(path.toRoundedRect(), null);
    });

    test('Should detect rectangular path is not round', () {
      final SurfacePath path = SurfacePath();
      path.addRect(const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0));
      expect(path.toRoundedRect(), null);
    });

    test(
        'Should detect non rounded  rectangular path if there are '
        'multiple subpaths', () {
      final SurfacePath path = SurfacePath();
      path.addRRect(RRect.fromRectAndRadius(
          const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0), const Radius.circular(2.0)));
      path.addRRect(RRect.fromRectAndRadius(
          const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0), const Radius.circular(2.0)));
      expect(path.toRoundedRect(), null);
    });

    test('Should compute bounds as empty for empty and moveTo only path', () {
      final Path emptyPath = Path();
      expect(emptyPath.getBounds(), Rect.zero);

      final SurfacePath path = SurfacePath();
      path.moveTo(50, 60);
      expect(path.getBounds(), const Rect.fromLTRB(50, 60, 50, 60));
    });

    test('Should compute bounds for multiple addRect calls', () {
      final Path emptyPath = Path();
      expect(emptyPath.getBounds(), Rect.zero);

      final SurfacePath path = SurfacePath();
      path.addRect(Rect.fromLTWH(0, 0, 270, 45));
      path.addRect(Rect.fromLTWH(134.5, 0, 1, 45));
      expect(path.getBounds(), const Rect.fromLTRB(0, 0, 270, 45));
    });

    test('Should compute bounds for addRRect', () {
      SurfacePath path = SurfacePath();
      final Rect bounds = Rect.fromLTRB(30, 40, 400, 300);
      RRect rrect = RRect.fromRectAndCorners(bounds,
          topLeft: Radius.elliptical(1, 2),
          topRight: Radius.elliptical(3, 4),
          bottomLeft: Radius.elliptical(5, 6),
          bottomRight: Radius.elliptical(7, 8));
      path.addRRect(rrect);
      expect(path.getBounds(), bounds);
      expect(path.toRoundedRect(), rrect);
      path = SurfacePath();
      rrect = RRect.fromRectAndCorners(bounds,
          topLeft: Radius.elliptical(0, 2),
          topRight: Radius.elliptical(3, 4),
          bottomLeft: Radius.elliptical(5, 6),
          bottomRight: Radius.elliptical(7, 8));
      path.addRRect(rrect);
      expect(path.getBounds(), bounds);
      expect(path.toRoundedRect(), rrect);
      path = SurfacePath();
      rrect = RRect.fromRectAndCorners(bounds,
          topLeft: Radius.elliptical(0, 0),
          topRight: Radius.elliptical(3, 4),
          bottomLeft: Radius.elliptical(5, 6),
          bottomRight: Radius.elliptical(7, 8));
      path.addRRect(rrect);
      expect(path.getBounds(), bounds);
      expect(path.toRoundedRect(), rrect);
      path = SurfacePath();
      rrect = RRect.fromRectAndCorners(bounds,
          topLeft: Radius.elliptical(1, 2),
          topRight: Radius.elliptical(0, 0),
          bottomLeft: Radius.elliptical(5, 6),
          bottomRight: Radius.elliptical(7, 8));
      path.addRRect(rrect);
      expect(path.getBounds(), bounds);
      expect(path.toRoundedRect(), rrect);
      path = SurfacePath();
      rrect = RRect.fromRectAndCorners(bounds,
          topLeft: Radius.elliptical(1, 2),
          topRight: Radius.elliptical(3, 4),
          bottomLeft: Radius.elliptical(0, 0),
          bottomRight: Radius.elliptical(7, 8));
      path.addRRect(rrect);
      expect(path.getBounds(), bounds);
      expect(path.toRoundedRect(), rrect);
      path = SurfacePath();
      rrect = RRect.fromRectAndCorners(bounds,
          topLeft: Radius.elliptical(1, 2),
          topRight: Radius.elliptical(3, 4),
          bottomLeft: Radius.elliptical(5, 6),
          bottomRight: Radius.elliptical(0, 0));
      path.addRRect(rrect);
      expect(path.getBounds(), bounds);
      expect(path.toRoundedRect(), rrect);
    });

    test('Should compute bounds for lines', () {
      final SurfacePath path = SurfacePath();
      path.moveTo(25, 30);
      path.lineTo(100, 200);
      expect(path.getBounds(), const Rect.fromLTRB(25, 30, 100, 200));

      final SurfacePath path2 = SurfacePath();
      path2.moveTo(250, 300);
      path2.lineTo(50, 60);
      expect(path2.getBounds(), const Rect.fromLTRB(50, 60, 250, 300));
    });

    test('Should compute bounds for polygon', () {
      final SurfacePath path = SurfacePath();
      path.addPolygon(<Offset>[
        Offset(50, 100),
        Offset(250, 100),
        Offset(152, 180),
        Offset(159, 200),
        Offset(151, 190)
      ], true);
      expect(path.getBounds(), const Rect.fromLTRB(50, 100, 250, 200));
    });

    test('Should compute bounds for quadraticBezierTo', () {
      final SurfacePath path1 = SurfacePath();
      path1.moveTo(285.2, 682.1);
      path1.quadraticBezierTo(432.0, 431.4, 594.9, 681.2);
      expect(
          path1.getBounds(),
          within<Rect>(
              distance: 0.1,
              from: const Rect.fromLTRB(285.2, 556.5, 594.9, 682.1)));

      // Control point below start , end.
      final SurfacePath path2 = SurfacePath();
      path2.moveTo(285.2, 682.1);
      path2.quadraticBezierTo(447.4, 946.8, 594.9, 681.2);
      expect(
          path2.getBounds(),
          within<Rect>(
              distance: 0.1,
              from: const Rect.fromLTRB(285.2, 681.2, 594.9, 814.2)));

      // Control point to the right of end point.
      final SurfacePath path3 = SurfacePath();
      path3.moveTo(468.3, 685.6);
      path3.quadraticBezierTo(644.7, 555.2, 594.9, 681.2);
      expect(
          path3.getBounds(),
          within<Rect>(
              distance: 0.1,
              from: const Rect.fromLTRB(468.3, 619.3, 605.9, 685.6)));
    });

    test('Should compute bounds for cubicTo', () {
      final SurfacePath path1 = SurfacePath();
      path1.moveTo(220, 300);
      path1.cubicTo(230, 120, 400, 125, 410, 280);
      expect(
          path1.getBounds(),
          within<Rect>(
              distance: 0.1,
              from: const Rect.fromLTRB(220.0, 164.3, 410.0, 300.0)));

      // control point 1 to the right of control point 2
      final SurfacePath path2 = SurfacePath();
      path2.moveTo(220, 300);
      path2.cubicTo(564.2, 13.7, 400.0, 125.0, 410.0, 280.0);
      expect(
          path2.getBounds(),
          within<Rect>(
              distance: 0.1,
              from: const Rect.fromLTRB(220.0, 122.8, 440.5, 300.0)));

      // control point 1 to the right of control point 2 inflection
      final SurfacePath path3 = SurfacePath();
      path3.moveTo(220, 300);
      path3.cubicTo(839.8, 67.9, 400.0, 125.0, 410.0, 280.0);
      expect(
          path3.getBounds(),
          within<Rect>(
              distance: 0.1,
              from: const Rect.fromLTRB(220.0, 144.5, 552.1, 300.0)));

      // control point 1 below and between start and end points
      final SurfacePath path4 = SurfacePath();
      path4.moveTo(220.0, 300.0);
      path4.cubicTo(354.8, 388.3, 400.0, 125.0, 410.0, 280.0);
      expect(
          path4.getBounds(),
          within<Rect>(
              distance: 0.1,
              from: const Rect.fromLTRB(220.0, 230.0, 410.0, 318.6)));

      // control points inverted below
      final SurfacePath path5 = SurfacePath();
      path5.moveTo(220.0, 300.0);
      path5.cubicTo(366.5, 487.3, 256.4, 489.9, 410.0, 280.0);
      expect(
          path5.getBounds(),
          within<Rect>(
              distance: 0.1,
              from: const Rect.fromLTRB(220.0, 280.0, 410.0, 439.0)));

      // control points inverted below wide
      final SurfacePath path6 = SurfacePath();
      path6.moveTo(220.0, 300.0);
      path6.cubicTo(496.1, 485.5, 121.4, 491.6, 410.0, 280.0);
      expect(
          path6.getBounds(),
          within<Rect>(
              distance: 0.1,
              from: const Rect.fromLTRB(220.0, 280.0, 410.0, 439.0)));

      // control point 2 and end point swapped
      final SurfacePath path7 = SurfacePath();
      path7.moveTo(220.0, 300.0);
      path7.cubicTo(230.0, 120.0, 394.5, 296.1, 382.3, 124.1);
      expect(
          path7.getBounds(),
          within<Rect>(
              distance: 0.1,
              from: const Rect.fromLTRB(220.0, 124.1, 382.9, 300.0)));
    });

    // Regression test for https://github.com/flutter/flutter/issues/46813.
    test('Should deep copy path', () {
      final SurfacePath path = SurfacePath();
      path.moveTo(25, 30);
      path.lineTo(100, 200);
      expect(path.getBounds(), const Rect.fromLTRB(25, 30, 100, 200));

      final SurfacePath path2 = SurfacePath.from(path);
      path2.lineTo(250, 300);
      expect(path2.getBounds(), const Rect.fromLTRB(25, 30, 250, 300));
      // Expect original path to stay the same.
      expect(path.getBounds(), const Rect.fromLTRB(25, 30, 100, 200));
    });

    test('Should handle contains inclusive right,bottom coordinates', () {
      final Path path = Path();
      path.moveTo(50, 60);
      path.lineTo(110, 60);
      path.lineTo(110, 190);
      path.lineTo(50, 190);
      path.close();
      expect(path.contains(Offset(80, 190)), true);
      expect(path.contains(Offset(110, 80)), true);
      expect(path.contains(Offset(110, 190)), true);
      expect(path.contains(Offset(110, 191)), false);
    });

    test('Should not contain top-left of beveled border', () {
      final Path path = Path();
      path.moveTo(10, 25);
      path.lineTo(15, 20);
      path.lineTo(25, 20);
      path.lineTo(30, 25);
      path.lineTo(30, 35);
      path.lineTo(25, 40);
      path.lineTo(15, 40);
      path.lineTo(10, 35);
      path.close();
      expect(path.contains(Offset(10, 20)), false);
    });

    test('Computes contains for cubic curves', () {
      final Path path = Path();
      path.moveTo(10, 25);
      path.cubicTo(10, 20, 10, 20,  20, 15);
      path.lineTo(25, 20);
      path.cubicTo(30, 20, 30, 20,  30, 25);
      path.lineTo(30, 35);
      path.cubicTo(30, 40, 30, 40,  25, 40);
      path.lineTo(15, 40);
      path.cubicTo(10, 40, 10,  40, 10, 35);
      path.close();
      expect(path.contains(Offset(10, 20)), false);
      expect(path.contains(Offset(30, 40)), false);
    });

    // Regression test for https://github.com/flutter/flutter/issues/44470
    test('Should handle contains for devicepixelratio != 1.0', () {
      js_util.setProperty(html.window, 'devicePixelRatio', 4.0);
      window.debugOverrideDevicePixelRatio(4.0);
      final Path path = Path()
        ..moveTo(50, 0)
        ..lineTo(100, 100)
        ..lineTo(0, 100)
        ..lineTo(50, 0)
        ..close();
      expect(path.contains(Offset(50, 50)), isTrue);
      js_util.setProperty(html.window, 'devicePixelRatio', 1.0);
      window.debugOverrideDevicePixelRatio(1.0);
      // TODO: Investigate failure on CI. Locally this passes.
      // [Exception... "Failure"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"
    }, skip: browserEngine == BrowserEngine.firefox);

    // Path contains should handle case where invalid RRect with large
    // corner radius is used for hit test. Use case is a RenderPhysicalShape
    // with a clipper that contains RRect of width/height 50 but corner radius
    // of 100.
    //
    // Regression test for https://github.com/flutter/flutter/issues/48887
    test('Should hit test correctly for malformed rrect', () {
      // Correctly formed rrect.
      final Path path1 = Path()
        ..addRRect(RRect.fromLTRBR(50, 50, 100, 100, Radius.circular(20)));
      expect(path1.contains(Offset(75, 75)), isTrue);
      expect(path1.contains(Offset(52, 75)), isTrue);
      expect(path1.contains(Offset(50, 50)), isFalse);
      expect(path1.contains(Offset(100, 50)), isFalse);
      expect(path1.contains(Offset(100, 100)), isFalse);
      expect(path1.contains(Offset(50, 100)), isFalse);

      final Path path2 = Path()
        ..addRRect(RRect.fromLTRBR(50, 50, 100, 100, Radius.circular(100)));
      expect(path2.contains(Offset(75, 75)), isTrue);
      expect(path2.contains(Offset(52, 75)), isTrue);
      expect(path2.contains(Offset(50, 50)), isFalse);
      expect(path2.contains(Offset(100, 50)), isFalse);
      expect(path2.contains(Offset(100, 100)), isFalse);
      expect(path2.contains(Offset(50, 100)), isFalse);
    });

    test('Should set segment masks', () {
      final SurfacePath path = SurfacePath();
      path.pathRef.computeSegmentMask();
      expect(path.pathRef.segmentMasks, 0);
      path.moveTo(20, 40);
      path.pathRef.computeSegmentMask();
      expect(path.pathRef.segmentMasks, 0);
      path.lineTo(200, 40);
      path.pathRef.computeSegmentMask();
      expect(
          path.pathRef.segmentMasks, SPathSegmentMask.kLine_SkPathSegmentMask);
    });

    test('Should convert conic to quad when approximation error is small', () {
      final Conic conic = Conic(120.0, 20.0, 160.99470420829266, 20.0,
          190.19301120261332, 34.38770865870253, 0.9252691032413082);
      expect(conic.toQuads().length, 3);
    });

    test('Should be able to construct from empty path', () {
      final SurfacePath path = SurfacePath();
      final SurfacePath? path2 = SurfacePath.from(path);
      assert(path2 != null, true);
    });
  });

  group('PathRef', () {
    test('Should return empty when created', () {
      final PathRef pathRef = PathRef();
      expect(pathRef.isEmpty, true);
    });

    test('Should return non-empty when mutated', () {
      final PathRef pathRef = PathRef();
      pathRef.growForVerb(SPath.kMoveVerb, 0);
      expect(pathRef.isEmpty, false);
    });
  });
  group('PathRefIterator', () {
    test('Should iterate through empty path', () {
      final Float32List points = Float32List(20);
      final PathRef pathRef = PathRef();
      final PathRefIterator iter = PathRefIterator(pathRef);
      expect(iter.next(points), SPath.kDoneVerb);
    });

    test('Should iterate through verbs', () {
      final Float32List points = Float32List(20);
      final PathRef pathRef = PathRef();
      pathRef.growForVerb(SPath.kMoveVerb, 0);
      pathRef.growForVerb(SPath.kLineVerb, 0);
      pathRef.growForVerb(SPath.kQuadVerb, 0);
      pathRef.growForVerb(SPath.kCubicVerb, 0);
      pathRef.growForVerb(SPath.kConicVerb, 0.8);
      pathRef.growForVerb(SPath.kLineVerb, 0.8);
      final PathRefIterator iter = PathRefIterator(pathRef);
      expect(iter.next(points), SPath.kMoveVerb);
      expect(iter.next(points), SPath.kLineVerb);
      expect(iter.next(points), SPath.kQuadVerb);
      expect(iter.next(points), SPath.kCubicVerb);
      expect(iter.next(points), SPath.kConicVerb);
      expect(iter.next(points), SPath.kLineVerb);
      expect(iter.next(points), SPath.kDoneVerb);
    });

    test('Should iterate by index through empty path', () {
      final PathRef pathRef = PathRef();
      final PathRefIterator iter = PathRefIterator(pathRef);
      expect(iter.nextIndex(), SPath.kDoneVerb);
    });

    test('Should iterate through contours', () {
      final PathRef pathRef = PathRef();
      pathRef.growForVerb(SPath.kMoveVerb, 0);
      pathRef.growForVerb(SPath.kLineVerb, 0);
      pathRef.growForVerb(SPath.kQuadVerb, 0);
      pathRef.growForVerb(SPath.kCubicVerb, 0);
      pathRef.growForVerb(SPath.kMoveVerb, 0);
      pathRef.growForVerb(SPath.kConicVerb, 0.8);
      pathRef.growForVerb(SPath.kLineVerb, 0.8);
      pathRef.growForVerb(SPath.kCloseVerb, 0.8);
      pathRef.growForVerb(SPath.kMoveVerb, 0);
      pathRef.growForVerb(SPath.kLineVerb, 0);
      pathRef.growForVerb(SPath.kLineVerb, 0);
      final PathRefIterator iter = PathRefIterator(pathRef);
      int start = iter.pointIndex;
      int end = iter.skipToNextContour();
      expect(end - start, 7);

      start = end;
      end = iter.skipToNextContour();
      expect(end - start, 4);

      start = end;
      end = iter.skipToNextContour();
      expect(end - start, 3);

      start = end;
      end = iter.skipToNextContour();
      expect(start, end);
    });

    /// Regression test for https://github.com/flutter/flutter/issues/68702.
    test('Path should return correct bounds after transform', () {
      final Path path1 = Path()
        ..moveTo(100, 100)
        ..lineTo(200, 100)
        ..lineTo(150, 200)
        ..close();
      final SurfacePath path2 = Path.from(path1) as SurfacePath;
      Rect bounds = path2.pathRef.getBounds();
      SurfacePath transformedPath = path2.transform(
          Matrix4.identity().scaled(0.5, 0.5).toFloat64());
      expect(transformedPath.pathRef.getBounds(), isNot(bounds));
    });
  });
}
