// 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' show window;

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(
      Directionality(
        textDirection: TextDirection.ltr,
        child: SemanticsDebugger(
          child: Directionality(
            textDirection: TextDirection.ltr,
            child: MediaQuery(
              data: MediaQueryData.fromWindow(window),
              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
    expect(value, equals(0.70));
  });

  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 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;
}
