// 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:ui';

import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

import 'semantics_tester.dart';

void main() {
  group(CustomPainter, () {
    setUp(() {
      debugResetSemanticsIdCounter();
      _PainterWithSemantics.shouldRebuildSemanticsCallCount = 0;
      _PainterWithSemantics.buildSemanticsCallCount = 0;
      _PainterWithSemantics.semanticsBuilderCallCount = 0;
    });

    _defineTests();
  });
}

void _defineTests() {
  testWidgets('builds no semantics by default', (WidgetTester tester) async {
    final SemanticsTester semanticsTester = SemanticsTester(tester);

    await tester.pumpWidget(CustomPaint(
      painter: _PainterWithoutSemantics(),
    ));

    expect(semanticsTester, hasSemantics(
      TestSemantics.root(),
    ));

    semanticsTester.dispose();
  });

  testWidgets('provides foreground semantics', (WidgetTester tester) async {
    final SemanticsTester semanticsTester = SemanticsTester(tester);

    await tester.pumpWidget(CustomPaint(
      foregroundPainter: _PainterWithSemantics(
        semantics: const CustomPainterSemantics(
          rect: Rect.fromLTRB(1.0, 1.0, 2.0, 2.0),
          properties: SemanticsProperties(
            label: 'foreground',
            textDirection: TextDirection.rtl,
          ),
        ),
      ),
    ));

    expect(semanticsTester, hasSemantics(
      TestSemantics.root(
        children: <TestSemantics>[
          TestSemantics.rootChild(
            id: 1,
            rect: TestSemantics.fullScreen,
            children: <TestSemantics>[
              TestSemantics(
                id: 2,
                label: 'foreground',
                rect: const Rect.fromLTRB(1.0, 1.0, 2.0, 2.0),
              ),
            ],
          ),
        ],
      ),
    ));

    semanticsTester.dispose();
  });

  testWidgets('provides background semantics', (WidgetTester tester) async {
    final SemanticsTester semanticsTester = SemanticsTester(tester);

    await tester.pumpWidget(CustomPaint(
      painter: _PainterWithSemantics(
        semantics: const CustomPainterSemantics(
          rect: Rect.fromLTRB(1.0, 1.0, 2.0, 2.0),
          properties: SemanticsProperties(
            label: 'background',
            textDirection: TextDirection.rtl,
          ),
        ),
      ),
    ));

    expect(semanticsTester, hasSemantics(
      TestSemantics.root(
        children: <TestSemantics>[
          TestSemantics.rootChild(
            id: 1,
            rect: TestSemantics.fullScreen,
            children: <TestSemantics>[
              TestSemantics(
                id: 2,
                label: 'background',
                rect: const Rect.fromLTRB(1.0, 1.0, 2.0, 2.0),
              ),
            ],
          ),
        ],
      ),
    ));

    semanticsTester.dispose();
  });

  testWidgets('combines background, child and foreground semantics', (WidgetTester tester) async {
    final SemanticsTester semanticsTester = SemanticsTester(tester);

    await tester.pumpWidget(CustomPaint(
      painter: _PainterWithSemantics(
        semantics: const CustomPainterSemantics(
          rect: Rect.fromLTRB(1.0, 1.0, 2.0, 2.0),
          properties: SemanticsProperties(
            label: 'background',
            textDirection: TextDirection.rtl,
          ),
        ),
      ),
      foregroundPainter: _PainterWithSemantics(
        semantics: const CustomPainterSemantics(
          rect: Rect.fromLTRB(1.0, 1.0, 2.0, 2.0),
          properties: SemanticsProperties(
            label: 'foreground',
            textDirection: TextDirection.rtl,
          ),
        ),
      ),
      child: Semantics(
        container: true,
        child: const Text('Hello', textDirection: TextDirection.ltr),
      ),
    ));

    expect(semanticsTester, hasSemantics(
      TestSemantics.root(
        children: <TestSemantics>[
          TestSemantics.rootChild(
            id: 1,
            rect: TestSemantics.fullScreen,
            children: <TestSemantics>[
              TestSemantics(
                id: 3,
                label: 'background',
                rect: const Rect.fromLTRB(1.0, 1.0, 2.0, 2.0),
              ),
              TestSemantics(
                id: 2,
                label: 'Hello',
                rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 600.0),
              ),
              TestSemantics(
                id: 4,
                label: 'foreground',
                rect: const Rect.fromLTRB(1.0, 1.0, 2.0, 2.0),
              ),
            ],
          ),
        ],
      ),
    ));

    semanticsTester.dispose();
  });

  testWidgets('applies $SemanticsProperties', (WidgetTester tester) async {
    final SemanticsTester semanticsTester = SemanticsTester(tester);

    await tester.pumpWidget(CustomPaint(
      painter: _PainterWithSemantics(
        semantics: const CustomPainterSemantics(
          key: ValueKey<int>(1),
          rect: Rect.fromLTRB(1.0, 2.0, 3.0, 4.0),
          properties: SemanticsProperties(
            checked: false,
            selected: false,
            button: false,
            label: 'label-before',
            value: 'value-before',
            increasedValue: 'increase-before',
            decreasedValue: 'decrease-before',
            hint: 'hint-before',
            textDirection: TextDirection.rtl,
          ),
        ),
      ),
    ));

    expect(semanticsTester, hasSemantics(
      TestSemantics.root(
        children: <TestSemantics>[
          TestSemantics.rootChild(
            id: 1,
            rect: TestSemantics.fullScreen,
            children: <TestSemantics>[
              TestSemantics(
                rect: const Rect.fromLTRB(1.0, 2.0, 3.0, 4.0),
                id: 2,
                flags: 1,
                label: 'label-before',
                value: 'value-before',
                increasedValue: 'increase-before',
                decreasedValue: 'decrease-before',
                hint: 'hint-before',
                textDirection: TextDirection.rtl,
              ),
            ],
          ),
        ],
      ),
    ));

    await tester.pumpWidget(CustomPaint(
      painter: _PainterWithSemantics(
        semantics: CustomPainterSemantics(
          key: const ValueKey<int>(1),
          rect: const Rect.fromLTRB(5.0, 6.0, 7.0, 8.0),
          properties: SemanticsProperties(
            checked: true,
            selected: true,
            button: true,
            label: 'label-after',
            value: 'value-after',
            increasedValue: 'increase-after',
            decreasedValue: 'decrease-after',
            hint: 'hint-after',
            textDirection: TextDirection.ltr,
            onScrollDown: () { },
            onLongPress: () { },
            onDecrease: () { },
            onIncrease: () { },
            onScrollLeft: () { },
            onScrollRight: () { },
            onScrollUp: () { },
            onTap: () { },
          ),
        ),
      ),
    ));

    expect(semanticsTester, hasSemantics(
      TestSemantics.root(
        children: <TestSemantics>[
          TestSemantics.rootChild(
            id: 1,
            rect: TestSemantics.fullScreen,
            children: <TestSemantics>[
              TestSemantics(
                rect: const Rect.fromLTRB(5.0, 6.0, 7.0, 8.0),
                actions: 255,
                id: 2,
                flags: 15,
                label: 'label-after',
                value: 'value-after',
                increasedValue: 'increase-after',
                decreasedValue: 'decrease-after',
                hint: 'hint-after',
                textDirection: TextDirection.ltr,
              ),
            ],
          ),
        ],
      ),
    ));

    semanticsTester.dispose();
  });

  testWidgets('Can toggle semantics on, off, on without crash', (WidgetTester tester) async {
    await tester.pumpWidget(CustomPaint(
      painter: _PainterWithSemantics(
        semantics: const CustomPainterSemantics(
          key: ValueKey<int>(1),
          rect: Rect.fromLTRB(1.0, 2.0, 3.0, 4.0),
          properties: SemanticsProperties(
            checked: false,
            selected: false,
            button: false,
            label: 'label-before',
            value: 'value-before',
            increasedValue: 'increase-before',
            decreasedValue: 'decrease-before',
            hint: 'hint-before',
            textDirection: TextDirection.rtl,
          ),
        ),
      ),
    ));

    // Start with semantics off.
    expect(tester.binding.pipelineOwner.semanticsOwner, isNull);

    // Semantics on
    SemanticsTester semantics = SemanticsTester(tester);
    await tester.pumpAndSettle();
    expect(tester.binding.pipelineOwner.semanticsOwner, isNotNull);

    // Semantics off
    semantics.dispose();
    await tester.pumpAndSettle();
    expect(tester.binding.pipelineOwner.semanticsOwner, isNull);

    // Semantics on
    semantics = SemanticsTester(tester);
    await tester.pumpAndSettle();
    expect(tester.binding.pipelineOwner.semanticsOwner, isNotNull);

    semantics.dispose();
  }, semanticsEnabled: false);

  testWidgets('Supports all actions', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    final List<SemanticsAction> performedActions = <SemanticsAction>[];

    await tester.pumpWidget(CustomPaint(
      painter: _PainterWithSemantics(
        semantics: CustomPainterSemantics(
          key: const ValueKey<int>(1),
          rect: const Rect.fromLTRB(1.0, 2.0, 3.0, 4.0),
          properties: SemanticsProperties(
            onDismiss: () => performedActions.add(SemanticsAction.dismiss),
            onTap: () => performedActions.add(SemanticsAction.tap),
            onLongPress: () => performedActions.add(SemanticsAction.longPress),
            onScrollLeft: () => performedActions.add(SemanticsAction.scrollLeft),
            onScrollRight: () => performedActions.add(SemanticsAction.scrollRight),
            onScrollUp: () => performedActions.add(SemanticsAction.scrollUp),
            onScrollDown: () => performedActions.add(SemanticsAction.scrollDown),
            onIncrease: () => performedActions.add(SemanticsAction.increase),
            onDecrease: () => performedActions.add(SemanticsAction.decrease),
            onCopy: () => performedActions.add(SemanticsAction.copy),
            onCut: () => performedActions.add(SemanticsAction.cut),
            onPaste: () => performedActions.add(SemanticsAction.paste),
            onMoveCursorForwardByCharacter: (bool _) => performedActions.add(SemanticsAction.moveCursorForwardByCharacter),
            onMoveCursorBackwardByCharacter: (bool _) => performedActions.add(SemanticsAction.moveCursorBackwardByCharacter),
            onMoveCursorForwardByWord: (bool _) => performedActions.add(SemanticsAction.moveCursorForwardByWord),
            onMoveCursorBackwardByWord: (bool _) => performedActions.add(SemanticsAction.moveCursorBackwardByWord),
            onSetSelection: (TextSelection _) => performedActions.add(SemanticsAction.setSelection),
            onSetText: (String text) => performedActions.add(SemanticsAction.setText),
            onDidGainAccessibilityFocus: () => performedActions.add(SemanticsAction.didGainAccessibilityFocus),
            onDidLoseAccessibilityFocus: () => performedActions.add(SemanticsAction.didLoseAccessibilityFocus),
          ),
        ),
      ),
    ));
    final Set<SemanticsAction> allActions = SemanticsAction.values.values.toSet()
      ..remove(SemanticsAction.customAction) // customAction is not user-exposed.
      ..remove(SemanticsAction.showOnScreen); // showOnScreen is not user-exposed

    const int expectedId = 2;
    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: 1,
          children: <TestSemantics>[
            TestSemantics.rootChild(
              id: expectedId,
              rect: TestSemantics.fullScreen,
              actions: allActions.fold<int>(0, (int previous, SemanticsAction action) => previous | action.index),
            ),
          ],
        ),
      ],
    );
    expect(semantics, hasSemantics(expectedSemantics, ignoreRect: true, ignoreTransform: true));

    // Do the actions work?
    final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!;
    int expectedLength = 1;
    for (final SemanticsAction action in allActions) {
      switch (action) {
        case SemanticsAction.moveCursorBackwardByCharacter:
        case SemanticsAction.moveCursorForwardByCharacter:
        case SemanticsAction.moveCursorBackwardByWord:
        case SemanticsAction.moveCursorForwardByWord:
          semanticsOwner.performAction(expectedId, action, true);
          break;
        case SemanticsAction.setSelection:
          semanticsOwner.performAction(expectedId, action, <String, int>{
            'base': 4,
            'extent': 5,
          });
          break;
        case SemanticsAction.setText:
          semanticsOwner.performAction(expectedId, action, 'text');
          break;
        case SemanticsAction.copy:
        case SemanticsAction.customAction:
        case SemanticsAction.cut:
        case SemanticsAction.decrease:
        case SemanticsAction.didGainAccessibilityFocus:
        case SemanticsAction.didLoseAccessibilityFocus:
        case SemanticsAction.dismiss:
        case SemanticsAction.increase:
        case SemanticsAction.longPress:
        case SemanticsAction.paste:
        case SemanticsAction.scrollDown:
        case SemanticsAction.scrollLeft:
        case SemanticsAction.scrollRight:
        case SemanticsAction.scrollUp:
        case SemanticsAction.showOnScreen:
        case SemanticsAction.tap:
          semanticsOwner.performAction(expectedId, action);
          break;
      }
      expect(performedActions.length, expectedLength);
      expect(performedActions.last, action);
      expectedLength += 1;
    }

    semantics.dispose();
  });

  testWidgets('Supports all flags', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    // checked state and toggled state are mutually exclusive.
    await tester.pumpWidget(CustomPaint(
      painter: _PainterWithSemantics(
        semantics: const CustomPainterSemantics(
          key: ValueKey<int>(1),
          rect: Rect.fromLTRB(1.0, 2.0, 3.0, 4.0),
          properties: SemanticsProperties(
            enabled: true,
            checked: true,
            selected: true,
            hidden: true,
            button: true,
            slider: true,
            keyboardKey: true,
            link: true,
            textField: true,
            readOnly: true,
            focused: true,
            focusable: true,
            inMutuallyExclusiveGroup: true,
            header: true,
            obscured: true,
            multiline: true,
            scopesRoute: true,
            namesRoute: true,
            image: true,
            liveRegion: true,
            toggled: true,
          ),
        ),
      ),
    ));
    List<SemanticsFlag> flags = SemanticsFlag.values.values.toList();
    // [SemanticsFlag.hasImplicitScrolling] isn't part of [SemanticsProperties]
    // therefore it has to be removed.
    flags.remove(SemanticsFlag.hasImplicitScrolling);
    TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
            id: 1,
            children: <TestSemantics>[
              TestSemantics.rootChild(
                id: 2,
                rect: TestSemantics.fullScreen,
                flags: flags,
              ),
            ],
        ),
      ],
    );
    expect(semantics, hasSemantics(expectedSemantics, ignoreRect: true, ignoreTransform: true));

    await tester.pumpWidget(CustomPaint(
      painter: _PainterWithSemantics(
        semantics: const CustomPainterSemantics(
          key: ValueKey<int>(1),
          rect: Rect.fromLTRB(1.0, 2.0, 3.0, 4.0),
          properties: SemanticsProperties(
            enabled: true,
            checked: true,
            toggled: true,
            selected: true,
            hidden: true,
            button: true,
            slider: true,
            keyboardKey: true,
            link: true,
            textField: true,
            readOnly: true,
            focused: true,
            focusable: true,
            inMutuallyExclusiveGroup: true,
            header: true,
            obscured: true,
            multiline: true,
            scopesRoute: true,
            namesRoute: true,
            image: true,
            liveRegion: true,
          ),
        ),
      ),
    ));
    flags = SemanticsFlag.values.values.toList();
    // [SemanticsFlag.hasImplicitScrolling] isn't part of [SemanticsProperties]
    // therefore it has to be removed.
    flags.remove(SemanticsFlag.hasImplicitScrolling);
    expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
            id: 1,
            children: <TestSemantics>[
              TestSemantics.rootChild(
                id: 2,
                rect: TestSemantics.fullScreen,
                flags: flags,
              ),
            ],
        ),
      ],
    );
    expect(semantics, hasSemantics(expectedSemantics, ignoreRect: true, ignoreTransform: true));
    semantics.dispose();
  });

  group('diffing', () {
    testWidgets('complains about duplicate keys', (WidgetTester tester) async {
      final SemanticsTester semanticsTester = SemanticsTester(tester);
      await tester.pumpWidget(CustomPaint(
        painter: _SemanticsDiffTest(<String>[
          'a-k',
          'a-k',
        ]),
      ));
      expect(tester.takeException(), isFlutterError);
      semanticsTester.dispose();
    });

    _testDiff('adds one item to an empty list', (_DiffTester tester) async {
      await tester.diff(
        from: <String>[],
        to: <String>['a'],
      );
    });

    _testDiff('removes the last item from the list', (_DiffTester tester) async {
      await tester.diff(
        from: <String>['a'],
        to: <String>[],
      );
    });

    _testDiff('appends one item at the end of a non-empty list', (_DiffTester tester) async {
      await tester.diff(
        from: <String>['a'],
        to: <String>['a', 'b'],
      );
    });

    _testDiff('prepends one item at the beginning of a non-empty list', (_DiffTester tester) async {
      await tester.diff(
        from: <String>['b'],
        to: <String>['a', 'b'],
      );
    });

    _testDiff('inserts one item in the middle of a list', (_DiffTester tester) async {
      await tester.diff(
        from: <String>[
          'a-k',
          'c-k',
        ],
        to: <String>[
          'a-k',
          'b-k',
          'c-k',
        ],
      );
    });

    _testDiff('removes one item from the middle of a list', (_DiffTester tester) async {
      await tester.diff(
        from: <String>[
          'a-k',
          'b-k',
          'c-k',
        ],
        to: <String>[
          'a-k',
          'c-k',
        ],
      );
    });

    _testDiff('swaps two items', (_DiffTester tester) async {
      await tester.diff(
        from: <String>[
          'a-k',
          'b-k',
        ],
        to: <String>[
          'b-k',
          'a-k',
        ],
      );
    });

    _testDiff('finds and moved one keyed item', (_DiffTester tester) async {
      await tester.diff(
        from: <String>[
          'a-k',
          'b',
          'c',
        ],
        to: <String>[
          'b',
          'c',
          'a-k',
        ],
      );
    });
  });

  testWidgets('rebuilds semantics upon resize', (WidgetTester tester) async {
    final SemanticsTester semanticsTester = SemanticsTester(tester);

    final _PainterWithSemantics painter = _PainterWithSemantics(
      semantics: const CustomPainterSemantics(
        rect: Rect.fromLTRB(1.0, 1.0, 2.0, 2.0),
        properties: SemanticsProperties(
          label: 'background',
          textDirection: TextDirection.rtl,
        ),
      ),
    );

    final CustomPaint paint = CustomPaint(painter: painter);

    await tester.pumpWidget(SizedBox(
      height: 20.0,
      width: 20.0,
      child: paint,
    ));
    expect(_PainterWithSemantics.shouldRebuildSemanticsCallCount, 0);
    expect(_PainterWithSemantics.buildSemanticsCallCount, 1);
    expect(_PainterWithSemantics.semanticsBuilderCallCount, 4);

    await tester.pumpWidget(SizedBox(
      height: 20.0,
      width: 20.0,
      child: paint,
    ));
    expect(_PainterWithSemantics.shouldRebuildSemanticsCallCount, 0);
    expect(_PainterWithSemantics.buildSemanticsCallCount, 1);
    expect(_PainterWithSemantics.semanticsBuilderCallCount, 4);

    await tester.pumpWidget(SizedBox(
      height: 40.0,
      width: 40.0,
      child: paint,
    ));
    expect(_PainterWithSemantics.shouldRebuildSemanticsCallCount, 0);
    expect(_PainterWithSemantics.buildSemanticsCallCount, 2);
    expect(_PainterWithSemantics.semanticsBuilderCallCount, 4);

    semanticsTester.dispose();
  });

  testWidgets('does not rebuild when shouldRebuildSemantics is false', (WidgetTester tester) async {
    final SemanticsTester semanticsTester = SemanticsTester(tester);

    const CustomPainterSemantics testSemantics = CustomPainterSemantics(
      rect: Rect.fromLTRB(1.0, 1.0, 2.0, 2.0),
      properties: SemanticsProperties(
        label: 'background',
        textDirection: TextDirection.rtl,
      ),
    );

    await tester.pumpWidget(CustomPaint(painter: _PainterWithSemantics(
      semantics: testSemantics,
    )));
    expect(_PainterWithSemantics.shouldRebuildSemanticsCallCount, 0);
    expect(_PainterWithSemantics.buildSemanticsCallCount, 1);
    expect(_PainterWithSemantics.semanticsBuilderCallCount, 4);

    await tester.pumpWidget(CustomPaint(painter: _PainterWithSemantics(
      semantics: testSemantics,
    )));
    expect(_PainterWithSemantics.shouldRebuildSemanticsCallCount, 1);
    expect(_PainterWithSemantics.buildSemanticsCallCount, 1);
    expect(_PainterWithSemantics.semanticsBuilderCallCount, 4);

    const CustomPainterSemantics testSemantics2 = CustomPainterSemantics(
      rect: Rect.fromLTRB(1.0, 1.0, 2.0, 2.0),
      properties: SemanticsProperties(
        label: 'background',
        textDirection: TextDirection.rtl,
      ),
    );

    await tester.pumpWidget(CustomPaint(painter: _PainterWithSemantics(
      semantics: testSemantics2,
    )));
    expect(_PainterWithSemantics.shouldRebuildSemanticsCallCount, 2);
    expect(_PainterWithSemantics.buildSemanticsCallCount, 1);
    expect(_PainterWithSemantics.semanticsBuilderCallCount, 4);

    semanticsTester.dispose();
  });
}

void _testDiff(String description, Future<void> Function(_DiffTester tester) testFunction) {
  testWidgets(description, (WidgetTester tester) async {
    await testFunction(_DiffTester(tester));
  });
}

class _DiffTester {
  _DiffTester(this.tester);

  final WidgetTester tester;

  /// Creates an initial semantics list using the `from` list, then updates the
  /// list to the `to` list. This causes [RenderCustomPaint] to diff the two
  /// lists and apply the changes. This method asserts the changes were
  /// applied correctly, specifically:
  ///
  /// - checks that initial and final configurations are in the desired states.
  /// - checks that keyed nodes have stable IDs.
  Future<void> diff({ required List<String> from, required List<String> to }) async {
    final SemanticsTester semanticsTester = SemanticsTester(tester);

    TestSemantics createExpectations(List<String> labels) {
      return TestSemantics.root(
        children: <TestSemantics>[
          TestSemantics.rootChild(
            rect: TestSemantics.fullScreen,
            children: <TestSemantics>[
              for (final String label in labels)
                TestSemantics(
                  rect: const Rect.fromLTRB(1.0, 1.0, 2.0, 2.0),
                  label: label,
                ),
            ],
          ),
        ],
      );
    }

    await tester.pumpWidget(CustomPaint(
      painter: _SemanticsDiffTest(from),
    ));
    expect(semanticsTester, hasSemantics(createExpectations(from), ignoreId: true));

    SemanticsNode root = RendererBinding.instance!.renderView.debugSemantics!;
    final Map<Key, int> idAssignments = <Key, int>{};
    root.visitChildren((SemanticsNode firstChild) {
      firstChild.visitChildren((SemanticsNode node) {
        if (node.key != null) {
          idAssignments[node.key!] = node.id;
        }
        return true;
      });
      return true;
    });

    await tester.pumpWidget(CustomPaint(
      painter: _SemanticsDiffTest(to),
    ));
    await tester.pumpAndSettle();
    expect(semanticsTester, hasSemantics(createExpectations(to), ignoreId: true));

    root = RendererBinding.instance!.renderView.debugSemantics!;
    root.visitChildren((SemanticsNode firstChild) {
      firstChild.visitChildren((SemanticsNode node) {
        if (node.key != null && idAssignments[node.key] != null) {
          expect(idAssignments[node.key], node.id, reason:
            'Node with key ${node.key} was previously assigned ID ${idAssignments[node.key]}. '
            'After diffing the child list, its ID changed to ${node.id}. IDs must be stable.',
          );
        }
        return true;
      });
      return true;
    });

    semanticsTester.dispose();
  }
}

class _SemanticsDiffTest extends CustomPainter {
  _SemanticsDiffTest(this.data);

  final List<String> data;

  @override
  void paint(Canvas canvas, Size size) {
    // We don't test painting.
  }

  @override
  SemanticsBuilderCallback get semanticsBuilder => buildSemantics;

  List<CustomPainterSemantics> buildSemantics(Size size) {
    final List<CustomPainterSemantics> semantics = <CustomPainterSemantics>[];
    for (final String label in data) {
      Key? key;
      if (label.endsWith('-k')) {
        key = ValueKey<String>(label);
      }
      semantics.add(
        CustomPainterSemantics(
          rect: const Rect.fromLTRB(1.0, 1.0, 2.0, 2.0),
          key: key,
          properties: SemanticsProperties(
            label: label,
            textDirection: TextDirection.rtl,
          ),
        ),
      );
    }
    return semantics;
  }

  @override
  bool shouldRepaint(_SemanticsDiffTest oldPainter) => true;
}

class _PainterWithSemantics extends CustomPainter {
  _PainterWithSemantics({ required this.semantics });

  final CustomPainterSemantics semantics;

  static int semanticsBuilderCallCount = 0;
  static int buildSemanticsCallCount = 0;
  static int shouldRebuildSemanticsCallCount = 0;

  @override
  void paint(Canvas canvas, Size size) {
    // We don't test painting.
  }

  @override
  SemanticsBuilderCallback get semanticsBuilder {
    semanticsBuilderCallCount += 1;
    return buildSemantics;
  }

  List<CustomPainterSemantics> buildSemantics(Size size) {
    buildSemanticsCallCount += 1;
    return <CustomPainterSemantics>[semantics];
  }

  @override
  bool shouldRepaint(_PainterWithSemantics oldPainter) {
    return true;
  }

  @override
  bool shouldRebuildSemantics(_PainterWithSemantics oldPainter) {
    shouldRebuildSemanticsCallCount += 1;
    return !identical(oldPainter.semantics, semantics);
  }
}

class _PainterWithoutSemantics extends CustomPainter {
  _PainterWithoutSemantics();

  @override
  void paint(Canvas canvas, Size size) {
    // We don't test painting.
  }

  @override
  bool shouldRepaint(_PainterWithSemantics oldPainter) => true;
}
