// Copyright 2014 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:async';
import 'dart:math' as math;
import 'dart:ui' as ui show Image;

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

import '../image_data.dart';
import '../rendering/mock_canvas.dart';

class TestImageProvider extends ImageProvider<TestImageProvider> {
  TestImageProvider(this.future);

  final Future<void> future;

  static late ui.Image image;

  @override
  Future<TestImageProvider> obtainKey(ImageConfiguration configuration) {
    return SynchronousFuture<TestImageProvider>(this);
  }

  @override
  ImageStreamCompleter load(TestImageProvider key, DecoderCallback decode) {
    return OneFrameImageStreamCompleter(
      future.then<ImageInfo>((void value) => ImageInfo(image: image)),
    );
  }
}

Future<void> main() async {
  AutomatedTestWidgetsFlutterBinding();
  TestImageProvider.image = await decodeImageFromList(Uint8List.fromList(kTransparentImage));

  testWidgets('DecoratedBox handles loading images', (WidgetTester tester) async {
    final GlobalKey key = GlobalKey();
    final Completer<void> completer = Completer<void>();
    await tester.pumpWidget(
      KeyedSubtree(
        key: key,
        child: DecoratedBox(
          decoration: BoxDecoration(
            image: DecorationImage(
              image: TestImageProvider(completer.future),
            ),
          ),
        ),
      ),
    );
    expect(tester.binding.hasScheduledFrame, isFalse);
    completer.complete();
    await tester.idle();
    expect(tester.binding.hasScheduledFrame, isTrue);
    await tester.pump();
    expect(tester.binding.hasScheduledFrame, isFalse);
  });

  testWidgets('Moving a DecoratedBox', (WidgetTester tester) async {
    final Completer<void> completer = Completer<void>();
    final Widget subtree = KeyedSubtree(
      key: GlobalKey(),
      child: RepaintBoundary(
        child: DecoratedBox(
          decoration: BoxDecoration(
            image: DecorationImage(
              image: TestImageProvider(completer.future),
            ),
          ),
        ),
      ),
    );
    await tester.pumpWidget(subtree);
    await tester.idle();
    expect(tester.binding.hasScheduledFrame, isFalse);
    await tester.pumpWidget(Container(child: subtree));
    await tester.idle();
    expect(tester.binding.hasScheduledFrame, isFalse);
    completer.complete(); // schedules microtask, does not run it
    expect(tester.binding.hasScheduledFrame, isFalse);
    await tester.idle(); // runs microtask
    expect(tester.binding.hasScheduledFrame, isTrue);
    await tester.pump();
    await tester.idle();
    expect(tester.binding.hasScheduledFrame, isFalse);
  });

  testWidgets('Circles can have uniform borders', (WidgetTester tester) async {
    await tester.pumpWidget(
      Container(
        padding: const EdgeInsets.all(50.0),
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          border: Border.all(width: 10.0, color: const Color(0x80FF00FF)),
          color: Colors.teal[600],
        ),
      ),
    );
  });

  testWidgets('Bordered Container insets its child', (WidgetTester tester) async {
    const Key key = Key('outerContainer');
    await tester.pumpWidget(
      Center(
        child: Container(
          key: key,
          decoration: BoxDecoration(border: Border.all(width: 10.0)),
          child: const SizedBox(
            width: 25.0,
            height: 25.0,
          ),
        ),
      ),
    );
    expect(tester.getSize(find.byKey(key)), equals(const Size(45.0, 45.0)));
  });

  testWidgets('BoxDecoration paints its border correctly', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/7672

    const Key key = Key('Container with BoxDecoration');
    Widget buildFrame(Border border) {
      return Center(
        child: Container(
          key: key,
          width: 100.0,
          height: 50.0,
          decoration: BoxDecoration(border: border),
        ),
      );
    }

    const Color black = Color(0xFF000000);

    await tester.pumpWidget(buildFrame(Border.all()));
    expect(find.byKey(key), paints..rect(color: black, style: PaintingStyle.stroke, strokeWidth: 1.0));

    await tester.pumpWidget(buildFrame(Border.all(width: 0.0)));
    expect(find.byKey(key), paints..rect(color: black, style: PaintingStyle.stroke, strokeWidth: 0.0));

    const Color green = Color(0xFF00FF00);
    const BorderSide greenSide = BorderSide(color: green, width: 10.0);

    await tester.pumpWidget(buildFrame(const Border(top: greenSide)));
    expect(find.byKey(key), paints..path(color: green, style: PaintingStyle.fill));

    await tester.pumpWidget(buildFrame(const Border(left: greenSide)));
    expect(find.byKey(key), paints..path(color: green, style: PaintingStyle.fill));

    await tester.pumpWidget(buildFrame(const Border(right: greenSide)));
    expect(find.byKey(key), paints..path(color: green, style: PaintingStyle.fill));

    await tester.pumpWidget(buildFrame(const Border(bottom: greenSide)));
    expect(find.byKey(key), paints..path(color: green, style: PaintingStyle.fill));

    const Color blue = Color(0xFF0000FF);
    const BorderSide blueSide = BorderSide(color: blue, width: 0.0);

    await tester.pumpWidget(buildFrame(const Border(top: blueSide, right: greenSide, bottom: greenSide)));
    expect(
      find.byKey(key),
      paints
        ..path() // There's not much point checking the arguments to these calls because paintBorder
        ..path() // reuses the same Paint object each time, configured differently, and so they will
        ..path(), // all appear to have the same settings here (that of the last call).
    );
  });

  testWidgets('BoxDecoration paints its border correctly', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/12165
    await tester.pumpWidget(
      Column(
        children: <Widget>[
          Container(
            // There's not currently a way to verify that this paints the same size as the others,
            // so the pattern below just asserts that there's four paths but doesn't check the geometry.
            width: 100.0,
            height: 100.0,
            decoration: const BoxDecoration(
              border: Border(
                top: BorderSide(
                  width: 10.0,
                  color: Color(0xFFEEEEEE),
                ),
                left: BorderSide(
                  width: 10.0,
                  color: Color(0xFFFFFFFF),
                ),
                right: BorderSide(
                  width: 10.0,
                  color: Color(0xFFFFFFFF),
                ),
                bottom: BorderSide(
                  width: 10.0,
                  color: Color(0xFFFFFFFF),
                ),
              ),
            ),
          ),
          Container(
            width: 100.0,
            height: 100.0,
            decoration: BoxDecoration(
              border: Border.all(
                width: 10.0,
                color: const Color(0xFFFFFFFF),
              ),
            ),
          ),
          Container(
            width: 100.0,
            height: 100.0,
            decoration: BoxDecoration(
              border: Border.all(
                width: 10.0,
                color: const Color(0xFFFFFFFF),
              ),
              borderRadius: const BorderRadius.only(
                topRight: Radius.circular(10.0),
              ),
            ),
          ),
          Container(
            width: 100.0,
            height: 100.0,
            decoration: BoxDecoration(
              border: Border.all(
                width: 10.0,
                color: const Color(0xFFFFFFFF),
              ),
              shape: BoxShape.circle,
            ),
          ),
        ],
      ),
    );
    expect(find.byType(Column), paints
      ..path()
      ..path()
      ..path()
      ..path()
      ..rect(rect: const Rect.fromLTRB(355.0, 105.0, 445.0, 195.0))
      ..drrect(
        outer: RRect.fromLTRBAndCorners(
          350.0, 200.0, 450.0, 300.0,
          topRight: const Radius.circular(10.0),
        ),
        inner: RRect.fromLTRBAndCorners(360.0, 210.0, 440.0, 290.0),
      )
      ..circle(x: 400.0, y: 350.0, radius: 45.0),
    );
  });

  testWidgets('Can hit test on BoxDecoration', (WidgetTester tester) async {

    late List<int> itemsTapped;

    const Key key = Key('Container with BoxDecoration');
    Widget buildFrame(Border border) {
      itemsTapped = <int>[];
      return Center(
        child: GestureDetector(
          behavior: HitTestBehavior.deferToChild,
          child: Container(
            key: key,
            width: 100.0,
            height: 50.0,
            decoration: BoxDecoration(border: border),
          ),
          onTap: () {
            itemsTapped.add(1);
          },
        ),
      );
    }

    await tester.pumpWidget(buildFrame(Border.all()));
    expect(itemsTapped, isEmpty);

    await tester.tap(find.byKey(key));
    expect(itemsTapped, <int>[1]);

    await tester.tapAt(const Offset(350.0, 275.0));
    expect(itemsTapped, <int>[1,1]);

    await tester.tapAt(const Offset(449.0, 324.0));
    expect(itemsTapped, <int>[1,1,1]);

  });

  testWidgets('Can hit test on BoxDecoration circle', (WidgetTester tester) async {

    late List<int> itemsTapped;

    const Key key = Key('Container with BoxDecoration');
    Widget buildFrame(Border border) {
      itemsTapped = <int>[];
      return Center(
        child: GestureDetector(
            behavior: HitTestBehavior.deferToChild,
            child: Container(
            key: key,
            width: 100.0,
            height: 50.0,
            decoration: BoxDecoration(border: border, shape: BoxShape.circle),
          ),
          onTap: () {
            itemsTapped.add(1);
          },
        ),
      );
    }

    await tester.pumpWidget(buildFrame(Border.all()));
    expect(itemsTapped, isEmpty);

    await tester.tapAt(Offset.zero);
    expect(itemsTapped, isEmpty);

    await tester.tapAt(const Offset(350.0, 275.0));
    expect(itemsTapped, isEmpty);

    await tester.tapAt(const Offset(400.0, 300.0));
    expect(itemsTapped, <int>[1]);

    await tester.tap(find.byKey(key));
    expect(itemsTapped, <int>[1,1]);

  });

  testWidgets('Can hit test on BoxDecoration border', (WidgetTester tester) async {
    late List<int> itemsTapped;
    const Key key = Key('Container with BoxDecoration');
    Widget buildFrame(Border border) {
      itemsTapped = <int>[];
      return Center(
        child: GestureDetector(
          behavior: HitTestBehavior.deferToChild,
          child: Container(
            key: key,
            width: 100.0,
            height: 50.0,
            decoration: BoxDecoration(border: border, borderRadius: const BorderRadius.all(Radius.circular(20.0))),
          ),
          onTap: () {
            itemsTapped.add(1);
          },
        ),
      );
    }

    await tester.pumpWidget(buildFrame(Border.all()));

    expect(itemsTapped, isEmpty);

    await tester.tapAt(Offset.zero);
    expect(itemsTapped, isEmpty);

    await tester.tapAt(const Offset(350.0, 275.0));
    expect(itemsTapped, isEmpty);

    await tester.tapAt(const Offset(400.0, 300.0));
    expect(itemsTapped, <int>[1]);

    await tester.tap(find.byKey(key));
    expect(itemsTapped, <int>[1,1]);
  });

  testWidgets('BoxDecoration not tap outside rounded angles - Top Left', (WidgetTester tester) async {
    const double height = 50.0;
    const double width = 50.0;
    const double radius = 12.3;

    late List<int> itemsTapped;
    const Key key = Key('Container with BoxDecoration');
    Widget buildFrame(Border border) {
      itemsTapped = <int>[];
      return Align(
        alignment: Alignment.topLeft,
        child: GestureDetector(
          behavior: HitTestBehavior.deferToChild,
          child: Container(
            key: key,
            width: width,
            height: height,
            decoration: BoxDecoration(border: border,borderRadius: BorderRadius.circular(radius)),
          ),
          onTap: () {
            itemsTapped.add(1);
          },
        ),
      );
    }

    await tester.pumpWidget(buildFrame(Border.all()));

    expect(itemsTapped, isEmpty);
    // x, y
    const Offset topLeft = Offset.zero;
    const Offset borderTopTangent = Offset(radius-1, 0.0);
    const Offset borderLeftTangent = Offset(0.0,radius-1);
    //the borderDiagonalOffset is the backslash line
    //\\######@@@
    //#\\###@####
    //##\\@######
    //##@########
    //@##########
    //@##########
    const double borderDiagonalOffset = radius - radius * math.sqrt1_2;
    const Offset fartherBorderRadiusPoint = Offset(borderDiagonalOffset,borderDiagonalOffset);

    await tester.tapAt(topLeft);
    expect(itemsTapped, isEmpty, reason: 'top left tapped');

    await tester.tapAt(borderTopTangent);
    expect(itemsTapped, isEmpty, reason: 'border top tapped');

    await tester.tapAt(borderLeftTangent);
    expect(itemsTapped, isEmpty, reason: 'border left tapped');

    await tester.tapAt(fartherBorderRadiusPoint);
    expect(itemsTapped, isEmpty, reason: 'border center tapped');

    await tester.tap(find.byKey(key));
    expect(itemsTapped, <int>[1]);

  });

  testWidgets('BoxDecoration tap inside rounded angles - Top Left', (WidgetTester tester) async {
    const double height = 50.0;
    const double width = 50.0;
    const double radius = 12.3;

    late List<int> itemsTapped;
    const Key key = Key('Container with BoxDecoration');
    Widget buildFrame(Border border) {
      itemsTapped = <int>[];
      return Align(
        alignment: Alignment.topLeft,
        child: GestureDetector(
          behavior: HitTestBehavior.deferToChild,
          child: Container(
            key: key,
            width: width,
            height: height,
            decoration: BoxDecoration(border: border,borderRadius: BorderRadius.circular(radius)),
          ),
          onTap: () {
            itemsTapped.add(1);
          },
        ),
      );
    }

    await tester.pumpWidget(buildFrame(Border.all()));

    expect(itemsTapped, isEmpty);
    // x, y
    const Offset borderTopTangent = Offset(radius, 0.0);
    const Offset borderLeftTangent = Offset(0.0,radius);
    const double borderDiagonalOffset = radius - radius * math.sqrt1_2;
    const Offset fartherBorderRadiusPoint = Offset(borderDiagonalOffset+1,borderDiagonalOffset+1);

    await tester.tapAt(borderTopTangent);
    expect(itemsTapped, <int>[1], reason: 'border Top not tapped');

    await tester.tapAt(borderLeftTangent);
    expect(itemsTapped, <int>[1,1], reason: 'border Left not tapped');

    await tester.tapAt(fartherBorderRadiusPoint);
    expect(itemsTapped, <int>[1,1,1], reason: 'border center not tapped');

    await tester.tap(find.byKey(key));
    expect(itemsTapped, <int>[1,1,1,1]);
  });

  testWidgets('BoxDecoration rounded angles other corner works', (WidgetTester tester) async {
    const double height = 50.0;
    const double width = 50.0;
    const double radius = 20;

    late List<int> itemsTapped;
    const Key key = Key('Container with BoxDecoration');
    Widget buildFrame(Border border) {
      itemsTapped = <int>[];
      return Align(
        alignment: Alignment.topLeft,
        child: GestureDetector(
          behavior: HitTestBehavior.deferToChild,
          child: Container(
            key: key,
            width: width,
            height: height,
            decoration: BoxDecoration(border: border,borderRadius: BorderRadius.circular(radius)),
          ),
          onTap: () {
            itemsTapped.add(1);
          },
        ),
      );
    }

    await tester.pumpWidget(buildFrame(Border.all()));

    expect(itemsTapped, isEmpty);

    await tester.tap(find.byKey(key));
    expect(itemsTapped, <int>[1]);

    // x, y
    const Offset topRightOutside = Offset(width, 0.0);
    const Offset topRightInside = Offset(width-radius, radius);
    const Offset bottomRightOutside = Offset(width, height);
    const Offset bottomRightInside = Offset(width-radius, height-radius);
    const Offset bottomLeftOutside = Offset(0, height);
    const Offset bottomLeftInside = Offset(radius, height-radius);
    const Offset topLeftOutside = Offset.zero;
    const Offset topLeftInside = Offset(radius, radius);

    await tester.tapAt(topRightInside);
    expect(itemsTapped, <int>[1,1], reason: 'top right not tapped');

    await tester.tapAt(topRightOutside);
    expect(itemsTapped, <int>[1,1], reason: 'top right tapped');

    await tester.tapAt(bottomRightInside);
    expect(itemsTapped, <int>[1,1,1], reason: 'bottom right not tapped');

    await tester.tapAt(bottomRightOutside);
    expect(itemsTapped, <int>[1,1,1], reason: 'bottom right tapped');

    await tester.tapAt(bottomLeftInside);
    expect(itemsTapped, <int>[1,1,1,1], reason: 'bottom left not tapped');

    await tester.tapAt(bottomLeftOutside);
    expect(itemsTapped, <int>[1,1,1,1], reason: 'bottom left tapped');

    await tester.tapAt(topLeftInside);
    expect(itemsTapped, <int>[1,1,1,1,1], reason: 'top left not tapped');

    await tester.tapAt(topLeftOutside);
    expect(itemsTapped, <int>[1,1,1,1,1], reason: 'top left tapped');
  });

  testWidgets("BoxDecoration doesn't crash with BorderRadiusDirectional", (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/88039

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(),
            borderRadius: const BorderRadiusDirectional.all(
              Radius.circular(1.0),
            ),
          ),
        ),
      ),
    );
  });
}
