// 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 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('SemanticsDebugger will schedule a frame', (WidgetTester tester) async {
    await tester.pumpWidget(
      SemanticsDebugger(
        child: Container(),
      ),
    );

    expect(tester.binding.hasScheduledFrame, isTrue);
  });

  testWidgets('SemanticsDebugger smoke test', (WidgetTester tester) async {

    // This is a smoketest to verify that adding a debugger doesn't crash.
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Stack(
          children: <Widget>[
            Semantics(),
            Semantics(
              container: true,
            ),
            Semantics(
              label: 'label',
              textDirection: TextDirection.ltr,
            ),
          ],
        ),
      ),
    );

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: SemanticsDebugger(
          child: Stack(
            children: <Widget>[
              Semantics(),
              Semantics(
                container: true,
              ),
              Semantics(
                label: 'label',
                textDirection: TextDirection.ltr,
              ),
            ],
          ),
        ),
      ),
    );

    expect(true, isTrue); // expect that we reach here without crashing
  });

  testWidgets('SemanticsDebugger reparents subtree', (WidgetTester tester) async {
    final GlobalKey key = GlobalKey();

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: SemanticsDebugger(
          child: Stack(
            children: <Widget>[
              Semantics(label: 'label1', textDirection: TextDirection.ltr),
              Positioned(
                key: key,
                left: 0.0,
                top: 0.0,
                width: 100.0,
                height: 100.0,
                child: Semantics(label: 'label2', textDirection: TextDirection.ltr),
              ),
            ],
          ),
        ),
      ),
    );

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: SemanticsDebugger(
          child: Stack(
            children: <Widget>[
              Semantics(label: 'label1', textDirection: TextDirection.ltr),
              Semantics(
                container: true,
                child: Stack(
                  children: <Widget>[
                    Positioned(
                      key: key,
                      left: 0.0,
                      top: 0.0,
                      width: 100.0,
                      height: 100.0,
                      child: Semantics(label: 'label2', textDirection: TextDirection.ltr),
                    ),
                    Semantics(label: 'label3', textDirection: TextDirection.ltr),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: SemanticsDebugger(
          child: Stack(
            children: <Widget>[
              Semantics(label: 'label1', textDirection: TextDirection.ltr),
              Semantics(
                container: true,
                child: Stack(
                  children: <Widget>[
                    Positioned(
                      key: key,
                      left: 0.0,
                      top: 0.0,
                      width: 100.0,
                      height: 100.0,
                      child: Semantics(label: 'label2', textDirection: TextDirection.ltr),
                    ),
                    Semantics(label: 'label3', textDirection: TextDirection.ltr),
                    Semantics(label: 'label4', textDirection: TextDirection.ltr),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );

    expect(tester.takeException(), isNull);
  });

  testWidgets('SemanticsDebugger interaction test', (WidgetTester tester) async {
    final List<String> log = <String>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: SemanticsDebugger(
          child: Material(
            child: ListView(
              children: <Widget>[
                ElevatedButton(
                  onPressed: () {
                    log.add('top');
                  },
                  child: const Text('TOP'),
                ),
                ElevatedButton(
                  onPressed: () {
                    log.add('bottom');
                  },
                  child: const Text('BOTTOM'),
                ),
              ],
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.text('TOP'), warnIfMissed: false); // hitting the debugger
    expect(log, equals(<String>['top']));
    log.clear();

    await tester.tap(find.text('BOTTOM'), warnIfMissed: false); // hitting the debugger
    expect(log, equals(<String>['bottom']));
    log.clear();
  });

  testWidgets('SemanticsDebugger interaction test - negative', (WidgetTester tester) async {
    final List<String> log = <String>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: SemanticsDebugger(
          child: Material(
            child: ListView(
              children: <Widget>[
                ElevatedButton(
                  onPressed: () {
                    log.add('top');
                  },
                  child: const Text('TOP', textDirection: TextDirection.ltr),
                ),
                ExcludeSemantics(
                  child: ElevatedButton(
                    onPressed: () {
                      log.add('bottom');
                    },
                    child: const Text('BOTTOM', textDirection: TextDirection.ltr),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.text('TOP'), warnIfMissed: false); // hitting the debugger
    expect(log, equals(<String>['top']));
    log.clear();

    await tester.tap(find.text('BOTTOM'), warnIfMissed: false); // hitting the debugger
    expect(log, equals(<String>[]));
    log.clear();
  });

  testWidgets('SemanticsDebugger scroll test', (WidgetTester tester) async {
    final Key childKey = UniqueKey();

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: SemanticsDebugger(
          child: ListView(
            children: <Widget>[
              Container(
                key: childKey,
                height: 5000.0,
                color: Colors.green[500],
              ),
            ],
          ),
        ),
      ),
    );

    expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(0.0));

    await tester.fling(find.byType(ListView), const Offset(0.0, -200.0), 200.0, warnIfMissed: false); // hitting the debugger);
    await tester.pump();

    expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(-480.0));

    await tester.fling(find.byType(ListView), const Offset(200.0, 0.0), 200.0, warnIfMissed: false); // hitting the debugger);
    await tester.pump();

    expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(-480.0));

    await tester.fling(find.byType(ListView), const Offset(-200.0, 0.0), 200.0, warnIfMissed: false); // hitting the debugger);
    await tester.pump();

    expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(-480.0));

    await tester.fling(find.byType(ListView), const Offset(0.0, 200.0), 200.0, warnIfMissed: false); // hitting the debugger);
    await tester.pump();

    expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(0.0));
  });

  testWidgets('SemanticsDebugger long press', (WidgetTester tester) async {
    bool didLongPress = false;

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: SemanticsDebugger(
          child: GestureDetector(
            onLongPress: () {
              expect(didLongPress, isFalse);
              didLongPress = true;
            },
            child: const Text('target', textDirection: TextDirection.ltr),
          ),
        ),
      ),
    );

    await tester.longPress(find.text('target'), warnIfMissed: false); // hitting the debugger
    expect(didLongPress, isTrue);
  });

  testWidgets('SemanticsDebugger slider', (WidgetTester tester) async {
    double value = 0.75;

    await tester.pumpWidget(
      MaterialApp(
        home: Directionality(
          textDirection: TextDirection.ltr,
          child: SemanticsDebugger(
            child: Directionality(
              textDirection: TextDirection.ltr,
              child: MediaQuery(
                data: MediaQueryData.fromView(tester.view),
                child: Material(
                  child: Center(
                    child: Slider(
                      value: value,
                      onChanged: (double newValue) {
                        value = newValue;
                      },
                    ),
                  ),
                ),
              ),
            ),
          ),
        )
      ),
    );

    // The fling below must be such that the velocity estimation examines an
    // offset greater than the kTouchSlop. Too slow or too short a distance, and
    // it won't trigger. The actual distance moved doesn't matter since this is
    // interpreted as a gesture by the semantics debugger and sent to the widget
    // as a semantic action that always moves by 10% of the complete track.
    await tester.fling(find.byType(Slider), const Offset(-100.0, 0.0), 2000.0, warnIfMissed: false); // hitting the debugger
    switch(defaultTargetPlatform) {
      case TargetPlatform.iOS:
      case TargetPlatform.macOS:
        expect(value, equals(0.65));
      case TargetPlatform.linux:
      case TargetPlatform.windows:
      case TargetPlatform.android:
      case TargetPlatform.fuchsia:
        expect(value, equals(0.70));
    }
  }, variant: TargetPlatformVariant.all());

  testWidgets('SemanticsDebugger checkbox', (WidgetTester tester) async {
    final Key keyTop = UniqueKey();
    final Key keyBottom = UniqueKey();

    bool? valueTop = false;

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: SemanticsDebugger(
          child: Material(
            child: ListView(
              children: <Widget>[
                Checkbox(
                  key: keyTop,
                  value: valueTop,
                  onChanged: (bool? newValue) {
                    valueTop = newValue;
                  },
                ),
                Checkbox(
                  key: keyBottom,
                  value: false,
                  onChanged: null,
                ),
              ],
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.byKey(keyTop), warnIfMissed: false); // hitting the debugger
    expect(valueTop, isTrue);
    valueTop = false;
    expect(valueTop, isFalse);

    await tester.tap(find.byKey(keyBottom), warnIfMissed: false); // hitting the debugger
    expect(valueTop, isFalse);
  });

  testWidgets('SemanticsDebugger checkbox message', (WidgetTester tester) async {
    final Key checkbox = UniqueKey();
    final Key checkboxUnchecked = UniqueKey();
    final Key checkboxDisabled = UniqueKey();
    final Key checkboxDisabledUnchecked = UniqueKey();
    final Key debugger = UniqueKey();

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: SemanticsDebugger(
          key: debugger,
          child: Material(
            child: ListView(
              children: <Widget>[
                Semantics(
                  container: true,
                  key: checkbox,
                  child: Checkbox(
                    value: true,
                    onChanged: (bool? _) { },
                  ),
                ),
                Semantics(
                  container: true,
                  key: checkboxUnchecked,
                  child: Checkbox(
                    value: false,
                    onChanged: (bool? _) { },
                  ),
                ),
                Semantics(
                  container: true,
                  key: checkboxDisabled,
                  child: const Checkbox(
                    value: true,
                    onChanged: null,
                  ),
                ),
                Semantics(
                  container: true,
                  key: checkboxDisabledUnchecked,
                  child: const Checkbox(
                    value: false,
                    onChanged: null,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );

    expect(
      _getMessageShownInSemanticsDebugger(widgetKey: checkbox, debuggerKey: debugger, tester: tester),
      'checked',
    );
    expect(
      _getMessageShownInSemanticsDebugger(widgetKey: checkboxUnchecked, debuggerKey: debugger, tester: tester),
      'unchecked',
    );
    expect(
      _getMessageShownInSemanticsDebugger(widgetKey: checkboxDisabled, debuggerKey: debugger, tester: tester),
      'checked; disabled',
    );
    expect(
      _getMessageShownInSemanticsDebugger(widgetKey: checkboxDisabledUnchecked, debuggerKey: debugger, tester: tester),
      'unchecked; disabled',
    );
  });

  testWidgets('SemanticsDebugger ignores duplicated label and tooltip for Android', (WidgetTester tester) async {
    final Key child = UniqueKey();
    final Key debugger = UniqueKey();
    final bool isPlatformAndroid = defaultTargetPlatform == TargetPlatform.android;
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: SemanticsDebugger(
          key: debugger,
          child: Material(
            child: Semantics(
              container: true,
              key: child,
              label: 'text',
              tooltip: 'text',
            ),
          ),
        ),
      ),
    );

    expect(
      _getMessageShownInSemanticsDebugger(widgetKey: child, debuggerKey: debugger, tester: tester),
      isPlatformAndroid ? 'text' : 'text\ntext',
    );
  }, variant: TargetPlatformVariant.all());

  testWidgets('SemanticsDebugger textfield', (WidgetTester tester) async {
    final UniqueKey textField = UniqueKey();
    final UniqueKey debugger = UniqueKey();

    await tester.pumpWidget(
      MaterialApp(
        home: SemanticsDebugger(
          key: debugger,
          child: Material(
            child: TextField(
              key: textField,
            ),
          ),
        ),
      ),
    );

    final dynamic semanticsDebuggerPainter = _getSemanticsDebuggerPainter(debuggerKey: debugger, tester: tester);
    final RenderObject renderTextfield = tester.renderObject(find.descendant(of: find.byKey(textField), matching: find.byType(Semantics)).first);

    expect(
      // ignore: avoid_dynamic_calls
      semanticsDebuggerPainter.getMessage(renderTextfield.debugSemantics),
      'textfield',
    );
  });

  testWidgets('SemanticsDebugger label style is used in the painter.', (WidgetTester tester) async {
    final UniqueKey debugger = UniqueKey();
    const TextStyle labelStyle = TextStyle(color: Colors.amber);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: SemanticsDebugger(
          key: debugger,
          labelStyle: labelStyle,
          child: Semantics(
            label: 'label',
            textDirection: TextDirection.ltr,
          ),
        ),
      ),
    );

    // ignore: avoid_dynamic_calls
    expect(_getSemanticsDebuggerPainter(debuggerKey: debugger, tester: tester).labelStyle, labelStyle);
  });
}

String _getMessageShownInSemanticsDebugger({
  required Key widgetKey,
  required Key debuggerKey,
  required WidgetTester tester,
}) {
  final dynamic semanticsDebuggerPainter = _getSemanticsDebuggerPainter(debuggerKey: debuggerKey, tester: tester);
  // ignore: avoid_dynamic_calls
  return semanticsDebuggerPainter.getMessage(tester.renderObject(find.byKey(widgetKey)).debugSemantics) as String;
}

dynamic _getSemanticsDebuggerPainter({
  required Key debuggerKey,
  required WidgetTester tester,
}) {
  final CustomPaint customPaint = tester.widgetList(find.descendant(
    of: find.byKey(debuggerKey),
    matching: find.byType(CustomPaint),
  )).first as CustomPaint;
  final dynamic semanticsDebuggerPainter = customPaint.foregroundPainter;
  expect(semanticsDebuggerPainter.runtimeType.toString(), '_SemanticsDebuggerPainter');
  return semanticsDebuggerPainter;
}
