// 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.

// This file is run as part of a reduced test set in CI on Mac and Windows
// machines.
@Tags(<String>['reduced-test-set'])
library;

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

void main() {
  testWidgets('DecoratedSliver creates, paints, and disposes BoxPainter', (WidgetTester tester) async {
    final TestDecoration decoration = TestDecoration();
    await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: CustomScrollView(
          slivers: <Widget>[
            DecoratedSliver(
              decoration: decoration,
              sliver: const SliverToBoxAdapter(
                child: SizedBox(width: 100, height: 100),
              ),
            )
          ],
        )
      )
    ));

    expect(decoration.painters, hasLength(1));
    expect(decoration.painters.last.lastConfiguration!.size, const Size(800, 100));
    expect(decoration.painters.last.lastOffset, Offset.zero);
    expect(decoration.painters.last.disposed, false);

    await tester.pumpWidget(const SizedBox());

    expect(decoration.painters, hasLength(1));
    expect(decoration.painters.last.disposed, true);
  });

  testWidgets('DecoratedSliver can update box painter', (WidgetTester tester) async {
    final TestDecoration decorationA = TestDecoration();
    final TestDecoration decorationB = TestDecoration();

    Decoration activateDecoration = decorationA;
    late StateSetter localSetState;
    await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            localSetState = setState;
            return CustomScrollView(
              slivers: <Widget>[
                DecoratedSliver(
                  decoration: activateDecoration,
                  sliver: const SliverToBoxAdapter(
                    child: SizedBox(width: 100, height: 100),
                  ),
                )
              ],
            );
          },
        )
      )
    ));

    expect(decorationA.painters, hasLength(1));
    expect(decorationA.painters.last.paintCount, 1);
    expect(decorationB.painters, hasLength(0));

    localSetState(() {
      activateDecoration = decorationB;
    });
    await tester.pump();

    expect(decorationA.painters, hasLength(1));
    expect(decorationB.painters, hasLength(1));
    expect(decorationB.painters.last.paintCount, 1);
  });

  testWidgets('DecoratedSliver can update DecorationPosition', (WidgetTester tester) async {
    final TestDecoration decoration = TestDecoration();

    DecorationPosition activePosition = DecorationPosition.foreground;
    late StateSetter localSetState;
    await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            localSetState = setState;
            return CustomScrollView(
              slivers: <Widget>[
                DecoratedSliver(
                  decoration: decoration,
                  position: activePosition,
                  sliver: const SliverToBoxAdapter(
                    child: SizedBox(width: 100, height: 100),
                  ),
                )
              ],
            );
          },
        )
      )
    ));

    expect(decoration.painters, hasLength(1));
    expect(decoration.painters.last.paintCount, 1);

    localSetState(() {
      activePosition = DecorationPosition.background;
    });
    await tester.pump();

    expect(decoration.painters, hasLength(1));
    expect(decoration.painters.last.paintCount, 2);
  });

  testWidgets('DecoratedSliver golden test', (WidgetTester tester) async {
    const BoxDecoration decoration = BoxDecoration(
      color: Colors.blue,
    );

    final Key backgroundKey = UniqueKey();
    await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: RepaintBoundary(
          key: backgroundKey,
          child: CustomScrollView(
            slivers: <Widget>[
              DecoratedSliver(
                decoration: decoration,
                sliver: SliverPadding(
                  padding: const EdgeInsets.all(16),
                  sliver: SliverList(
                    delegate: SliverChildListDelegate.fixed(<Widget>[
                      Container(
                        height: 100,
                        color: Colors.red,
                      ),
                      Container(
                        height: 100,
                        color: Colors.yellow,
                      ),
                      Container(
                        height: 100,
                        color: Colors.red,
                      ),
                    ]),
                  ),
                ),
              ),
            ],
          ),
        ),
      )
    ));

    await expectLater(find.byKey(backgroundKey), matchesGoldenFile('decorated_sliver.moon.background.png'));

    final Key foregroundKey = UniqueKey();
     await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: RepaintBoundary(
          key: foregroundKey,
          child: CustomScrollView(
            slivers: <Widget>[
              DecoratedSliver(
                decoration: decoration,
                position: DecorationPosition.foreground,
                sliver: SliverPadding(
                  padding: const EdgeInsets.all(16),
                  sliver: SliverList(
                    delegate: SliverChildListDelegate.fixed(<Widget>[
                      Container(
                        height: 100,
                        color: Colors.red,
                      ),
                      Container(
                        height: 100,
                        color: Colors.yellow,
                      ),
                      Container(
                        height: 100,
                        color: Colors.red,
                      ),
                    ]),
                  ),
                ),
              ),
            ],
          ),
        ),
      )
    ));

    await expectLater(find.byKey(foregroundKey), matchesGoldenFile('decorated_sliver.moon.foreground.png'));
  });

  testWidgets('DecoratedSliver paints its border correctly vertically', (WidgetTester tester) async {
    const Key key = Key('DecoratedSliver with border');
    const Color black = Color(0xFF000000);
    final ScrollController controller = ScrollController();
    addTearDown(controller.dispose);
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: Align(
        alignment: Alignment.topLeft,
        child: SizedBox(
          height: 300,
          width: 100,
          child: CustomScrollView(
            controller: controller,
            slivers: <Widget>[
              DecoratedSliver(
                key: key,
                decoration: BoxDecoration(border: Border.all()),
                sliver: const SliverToBoxAdapter(
                  child: SizedBox(width: 100, height: 500),
                ),
              ),
            ],
          ),
        ),
      ),
    ));
    controller.jumpTo(200);
    await tester.pumpAndSettle();
    expect(find.byKey(key), paints..rect(
      rect: const Offset(0.5, -199.5) & const Size(99, 499),
      color: black,
      style: PaintingStyle.stroke,
      strokeWidth: 1.0,
    ));
  });

  testWidgets('DecoratedSliver paints its border correctly vertically reverse', (WidgetTester tester) async {
    const Key key = Key('DecoratedSliver with border');
    const Color black = Color(0xFF000000);
    final ScrollController controller = ScrollController();
    addTearDown(controller.dispose);
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: Align(
        alignment: Alignment.topLeft,
        child: SizedBox(
          height: 300,
          width: 100,
          child: CustomScrollView(
            controller: controller,
            reverse: true,
            slivers: <Widget>[
              DecoratedSliver(
                key: key,
                decoration: BoxDecoration(border: Border.all()),
                sliver: const SliverToBoxAdapter(
                  child: SizedBox(width: 100, height: 500),
                ),
              ),
            ],
          ),
        ),
      ),
    ));
    controller.jumpTo(200);
    await tester.pumpAndSettle();
    expect(find.byKey(key), paints..rect(
      rect: const Offset(0.5, -199.5) & const Size(99, 499),
      color: black,
      style: PaintingStyle.stroke,
      strokeWidth: 1.0,
    ));
  });



  testWidgets('DecoratedSliver paints its border correctly horizontally', (WidgetTester tester) async {
    const Key key = Key('DecoratedSliver with border');
    const Color black = Color(0xFF000000);
    final ScrollController controller = ScrollController();
    addTearDown(controller.dispose);
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: Align(
        alignment: Alignment.topLeft,
        child: SizedBox(
          height: 100,
          width: 300,
          child: CustomScrollView(
            scrollDirection: Axis.horizontal,
            controller: controller,
            slivers: <Widget>[
              DecoratedSliver(
                key: key,
                decoration: BoxDecoration(border: Border.all()),
                sliver: const SliverToBoxAdapter(
                  child: SizedBox(width: 500, height: 100),
                ),
              ),
            ],
          ),
        ),
      ),
    ));
    controller.jumpTo(200);
    await tester.pumpAndSettle();
    expect(find.byKey(key), paints..rect(
      rect: const Offset(-199.5, 0.5) & const Size(499, 99),
      color: black,
      style: PaintingStyle.stroke,
      strokeWidth: 1.0,
    ));
  });

  testWidgets('DecoratedSliver paints its border correctly horizontally reverse', (WidgetTester tester) async {
    const Key key = Key('DecoratedSliver with border');
    const Color black = Color(0xFF000000);
    final ScrollController controller = ScrollController();
    addTearDown(controller.dispose);
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: Align(
        alignment: Alignment.topLeft,
        child: SizedBox(
          height: 100,
          width: 300,
          child: CustomScrollView(
            scrollDirection: Axis.horizontal,
            reverse: true,
            controller: controller,
            slivers: <Widget>[
              DecoratedSliver(
                key: key,
                decoration: BoxDecoration(border: Border.all()),
                sliver: const SliverToBoxAdapter(
                  child: SizedBox(width: 500, height: 100),
                ),
              ),
            ],
          ),
        ),
      ),
    ));
    controller.jumpTo(200);
    await tester.pumpAndSettle();
    expect(find.byKey(key), paints..rect(
      rect: const Offset(-199.5, 0.5) & const Size(499, 99),
      color: black,
      style: PaintingStyle.stroke,
      strokeWidth: 1.0,
    ));
  });


  testWidgets('DecoratedSliver works with SliverMainAxisGroup', (WidgetTester tester) async {
    const Key key = Key('DecoratedSliver with border');
    const Color black = Color(0xFF000000);
    final ScrollController controller = ScrollController();
    addTearDown(controller.dispose);
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: Align(
        alignment: Alignment.topLeft,
        child: SizedBox(
          height: 100,
          width: 300,
          child: CustomScrollView(
            controller: controller,
            slivers: <Widget>[
              DecoratedSliver(
                key: key,
                decoration: BoxDecoration(border: Border.all()),
                sliver: const SliverMainAxisGroup(
                  slivers: <Widget>[
                    SliverToBoxAdapter(child: SizedBox(height: 100)),
                    SliverToBoxAdapter(child: SizedBox(height: 100)),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    ));
    await tester.pumpAndSettle();
    expect(find.byKey(key), paints..rect(
      rect: const Offset(0.5, 0.5) & const Size(299, 199),
      color: black,
      style: PaintingStyle.stroke,
      strokeWidth: 1.0,
    ));
  });

  testWidgets('DecoratedSliver works with SliverCrossAxisGroup', (WidgetTester tester) async {
    const Key key = Key('DecoratedSliver with border');
    const Color black = Color(0xFF000000);
    final ScrollController controller = ScrollController();
    addTearDown(controller.dispose);
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: Align(
        alignment: Alignment.topLeft,
        child: SizedBox(
          height: 100,
          width: 300,
          child: CustomScrollView(
            controller: controller,
            slivers: <Widget>[
              DecoratedSliver(
                key: key,
                decoration: BoxDecoration(border: Border.all()),
                sliver: const SliverCrossAxisGroup(
                  slivers: <Widget>[
                    SliverToBoxAdapter(child: SizedBox(height: 100)),
                    SliverToBoxAdapter(child: SizedBox(height: 100)),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    ));
    await tester.pumpAndSettle();
    expect(find.byKey(key), paints..rect(
      rect: const Offset(0.5, 0.5) & const Size(299, 99),
      color: black,
      style: PaintingStyle.stroke,
      strokeWidth: 1.0,
    ));
  });

  testWidgets('DecoratedSliver draws only up to the bottom cache when sliver has infinite scroll extent', (WidgetTester tester) async {
    const Key key = Key('DecoratedSliver with border');
    const Color black = Color(0xFF000000);
    final ScrollController controller = ScrollController();
    addTearDown(controller.dispose);
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: Align(
        alignment: Alignment.topLeft,
        child: SizedBox(
          height: 100,
          width: 300,
          child: CustomScrollView(
            controller: controller,
            slivers: <Widget>[
              DecoratedSliver(
                key: key,
                decoration: BoxDecoration(border: Border.all()),
                sliver: SliverList.builder(
                  itemBuilder: (BuildContext context, int index) => const SizedBox(height: 100),
                ),
              ),
            ],
          ),
        ),
      ),
    ));
    expect(find.byKey(key), paints..rect(
      rect: const Offset(0.5, 0.5) & const Size(299, 349),
      color: black,
      style: PaintingStyle.stroke,
      strokeWidth: 1.0,
    ));
    controller.jumpTo(200);
    await tester.pumpAndSettle();
    // Note that the bottom edge is of the rect is the same as above.
    expect(find.byKey(key), paints..rect(
      rect: const Offset(0.5, -199.5) & const Size(299, 549),
      color: black,
      style: PaintingStyle.stroke,
      strokeWidth: 1.0,
    ));
  });
}

class TestDecoration extends Decoration {
  final List<TestBoxPainter> painters = <TestBoxPainter>[];

  @override
  BoxPainter createBoxPainter([VoidCallback? onChanged]) {
    final TestBoxPainter painter = TestBoxPainter();
    painters.add(painter);
    return painter;
  }
}

class TestBoxPainter extends BoxPainter {
  Offset? lastOffset;
  ImageConfiguration? lastConfiguration;
  bool disposed = false;
  int paintCount = 0;

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
    lastOffset = offset;
    lastConfiguration = configuration;
    paintCount += 1;
  }

  @override
  void dispose() {
    assert(!disposed);
    disposed = true;
    super.dispose();
  }
}
