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

void main() {
  final binding = TestAutomatedTestWidgetsFlutterBinding();

  testWidgets('English translations exist for all WidgetsLocalizations properties', (
    WidgetTester tester,
  ) async {
    const WidgetsLocalizations localizations = DefaultWidgetsLocalizations();

    expect(localizations.reorderItemUp, isNotNull);
    expect(localizations.reorderItemDown, isNotNull);
    expect(localizations.reorderItemLeft, isNotNull);
    expect(localizations.reorderItemRight, isNotNull);
    expect(localizations.reorderItemToEnd, isNotNull);
    expect(localizations.reorderItemToStart, isNotNull);
    expect(localizations.searchResultsFound, isNotNull);
    expect(localizations.noResultsFound, isNotNull);
    expect(localizations.copyButtonLabel, isNotNull);
    expect(localizations.cutButtonLabel, isNotNull);
    expect(localizations.pasteButtonLabel, isNotNull);
    expect(localizations.selectAllButtonLabel, isNotNull);
    expect(localizations.lookUpButtonLabel, isNotNull);
    expect(localizations.searchWebButtonLabel, isNotNull);
    expect(localizations.shareButtonLabel, isNotNull);
  });

  testWidgets('Locale is available when Localizations widget stops deferring frames', (
    WidgetTester tester,
  ) async {
    final delegate = FakeLocalizationsDelegate();
    await tester.pumpWidget(
      Localizations(
        locale: const Locale('fo'),
        delegates: <LocalizationsDelegate<dynamic>>[WidgetsLocalizationsDelegate(), delegate],
        child: const Text('loaded'),
      ),
    );
    final dynamic state = tester.state(find.byType(Localizations));
    // ignore: avoid_dynamic_calls
    expect(state!.locale, isNull);
    expect(find.text('loaded'), findsNothing);

    late Locale locale;
    binding.onAllowFrame = () {
      // ignore: avoid_dynamic_calls
      locale = state.locale as Locale;
    };
    delegate.completer.complete('foo');
    await tester.idle();
    expect(locale, const Locale('fo'));
    await tester.pump();
    expect(find.text('loaded'), findsOneWidget);
  });

  testWidgets('Locale is sent to engine if this is a top level Localizations', (
    WidgetTester tester,
  ) async {
    final delegate = FakeLocalizationsDelegate();
    await tester.pumpWidget(
      Localizations(
        locale: const Locale('fo'),
        isApplicationLevel: true,
        delegates: <LocalizationsDelegate<dynamic>>[WidgetsLocalizationsDelegate(), delegate],
        child: const Text('loaded'),
      ),
    );
    delegate.completer.complete('foo');
    await tester.idle();
    await tester.pump();
    expect(tester.binding.platformDispatcher.applicationLocale, const Locale('fo'));
  });

  testWidgets('Localizations.localeOf throws when no localizations exist', (
    WidgetTester tester,
  ) async {
    final GlobalKey contextKey = GlobalKey(debugLabel: 'Test Key');
    await tester.pumpWidget(Container(key: contextKey));

    expect(
      () => Localizations.localeOf(contextKey.currentContext!),
      throwsA(
        isAssertionError.having(
          (AssertionError e) => e.message,
          'message',
          contains('does not include a Localizations ancestor'),
        ),
      ),
    );
  });

  testWidgets('Localizations.maybeLocaleOf returns null when no localizations exist', (
    WidgetTester tester,
  ) async {
    final GlobalKey contextKey = GlobalKey(debugLabel: 'Test Key');
    await tester.pumpWidget(Container(key: contextKey));

    expect(Localizations.maybeLocaleOf(contextKey.currentContext!), isNull);
  });

  testWidgets('LocalizationsResolver.update notifies listeners when supportedLocales changes', (
    WidgetTester tester,
  ) async {
    final resolver = LocalizationsResolver(supportedLocales: <Locale>[const Locale('en')]);

    var notified = false;
    resolver.addListener(() {
      notified = true;
    });

    resolver.update(
      locale: null,
      localeListResolutionCallback: null,
      localeResolutionCallback: null,
      localizationsDelegates: null,
      supportedLocales: <Locale>[const Locale('de')],
    );

    expect(notified, isTrue);
    resolver.dispose();
  });

  testWidgets('LocalizationsResolver.update does not notify when resolved locale unchanged', (
    WidgetTester tester,
  ) async {
    final resolver = LocalizationsResolver(
      supportedLocales: <Locale>[const Locale('en'), const Locale('de')],
    );

    var notified = false;
    resolver.addListener(() {
      notified = true;
    });

    // Update with the same effective supportedLocales shouldn't change resolved locale.
    resolver.update(
      locale: null,
      localeListResolutionCallback: null,
      localeResolutionCallback: null,
      localizationsDelegates: null,
      supportedLocales: <Locale>[const Locale('en'), const Locale('de')],
    );

    expect(notified, isFalse);
    resolver.dispose();
  });

  group('Semantics', () {
    testWidgets('set locale semantics', (WidgetTester tester) async {
      await tester.pumpWidget(
        Localizations(
          locale: const Locale('fo'),
          delegates: <LocalizationsDelegate<dynamic>>[WidgetsLocalizationsDelegate()],
          child: Semantics(
            container: true,
            label: '1',
            explicitChildNodes: true,
            child: Column(
              children: <Widget>[
                const Text('2'),
                Localizations(
                  locale: const Locale('zh'),
                  delegates: <LocalizationsDelegate<dynamic>>[WidgetsLocalizationsDelegate()],
                  child: const Text('3'),
                ),
              ],
            ),
          ),
        ),
      );
      final SemanticsNode node1 = tester.getSemantics(find.bySemanticsLabel('1'));
      expect(node1.getSemanticsData().locale, const Locale('fo'));

      final SemanticsNode node2 = tester.getSemantics(find.bySemanticsLabel('2'));
      expect(node2.getSemanticsData().locale, const Locale('fo'));

      final SemanticsNode node3 = tester.getSemantics(find.bySemanticsLabel('3'));
      expect(node3.getSemanticsData().locale, const Locale('zh'));
    });

    testWidgets('application level does not set semantics', (WidgetTester tester) async {
      await tester.pumpWidget(
        Localizations(
          locale: const Locale('fo'),
          isApplicationLevel: true,
          delegates: <LocalizationsDelegate<dynamic>>[WidgetsLocalizationsDelegate()],
          child: Semantics(
            container: true,
            label: '1',
            explicitChildNodes: true,
            child: const Column(children: <Widget>[Text('2'), Text('3')]),
          ),
        ),
      );
      final SemanticsNode node1 = tester.getSemantics(find.bySemanticsLabel('1'));
      expect(node1.getSemanticsData().locale, isNull);

      final SemanticsNode node2 = tester.getSemantics(find.bySemanticsLabel('2'));
      expect(node2.getSemanticsData().locale, isNull);

      final SemanticsNode node3 = tester.getSemantics(find.bySemanticsLabel('3'));
      expect(node3.getSemanticsData().locale, isNull);
    });
  });

  testWidgets('Localizations does not crash at zero area', (WidgetTester tester) async {
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: SizedBox.shrink(
            child: Localizations(
              locale: const Locale('fo'),
              delegates: <LocalizationsDelegate<dynamic>>[WidgetsLocalizationsDelegate()],
              child: const Text('X'),
            ),
          ),
        ),
      ),
    );
    expect(tester.getSize(find.byType(Localizations)), Size.zero);
  });
}

class FakeLocalizationsDelegate extends LocalizationsDelegate<String> {
  final Completer<String> completer = Completer<String>();

  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<String> load(Locale locale) => completer.future;

  @override
  bool shouldReload(LocalizationsDelegate<String> old) => false;
}

class TestAutomatedTestWidgetsFlutterBinding extends AutomatedTestWidgetsFlutterBinding {
  VoidCallback? onAllowFrame;

  @override
  void allowFirstFrame() {
    onAllowFrame?.call();
    super.allowFirstFrame();
  }
}

class WidgetsLocalizationsDelegate extends LocalizationsDelegate<WidgetsLocalizations> {
  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<WidgetsLocalizations> load(Locale locale) => DefaultWidgetsLocalizations.load(locale);

  @override
  bool shouldReload(WidgetsLocalizationsDelegate old) => false;
}
