// 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_localizations/flutter_localizations.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:intl/intl.dart' as intl;

class FooMaterialLocalizations extends MaterialLocalizationEn {
  FooMaterialLocalizations(
    Locale localeName,
    this.backButtonTooltip,
  ) : super(
    localeName: localeName.toString(),
    fullYearFormat: intl.DateFormat.y(),
    compactDateFormat: intl.DateFormat.yMd(),
    shortDateFormat: intl.DateFormat.yMMMd(),
    mediumDateFormat: intl.DateFormat('E, MMM\u00a0d'),
    longDateFormat: intl.DateFormat.yMMMMEEEEd(),
    yearMonthFormat: intl.DateFormat.yMMMM(),
    shortMonthDayFormat: intl.DateFormat.MMMd(),
    decimalFormat: intl.NumberFormat.decimalPattern(),
    twoDigitZeroPaddedFormat: intl.NumberFormat('00'),
  );

  @override
  final String backButtonTooltip;
}

class FooMaterialLocalizationsDelegate extends LocalizationsDelegate<MaterialLocalizations> {
  const FooMaterialLocalizationsDelegate({
    this.supportedLanguage = 'en',
    this.backButtonTooltip = 'foo',
  });

  final String supportedLanguage;
  final String backButtonTooltip;

  @override
  bool isSupported(Locale locale) {
    return supportedLanguage == 'allLanguages' || locale.languageCode == supportedLanguage;
  }

  @override
  Future<FooMaterialLocalizations> load(Locale locale) {
    return SynchronousFuture<FooMaterialLocalizations>(FooMaterialLocalizations(locale, backButtonTooltip));
  }

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

Widget buildFrame({
  Locale locale,
  Iterable<LocalizationsDelegate<dynamic>> delegates = GlobalMaterialLocalizations.delegates,
  WidgetBuilder buildContent,
  LocaleResolutionCallback localeResolutionCallback,
  Iterable<Locale> supportedLocales = const <Locale>[
    Locale('en', 'US'),
    Locale('es', 'ES'),
  ],
}) {
  return MaterialApp(
    color: const Color(0xFFFFFFFF),
    locale: locale,
    supportedLocales: supportedLocales,
    localizationsDelegates: delegates,
    localeResolutionCallback: localeResolutionCallback,
    onGenerateRoute: (RouteSettings settings) {
      return MaterialPageRoute<void>(
        builder: (BuildContext context) {
          return buildContent(context);
        }
      );
    },
  );
}

void main() {
  testWidgets('Locale fallbacks', (WidgetTester tester) async {
    final Key textKey = UniqueKey();

    await tester.pumpWidget(
      buildFrame(
        buildContent: (BuildContext context) {
          return Text(
            MaterialLocalizations.of(context).backButtonTooltip,
            key: textKey,
          );
        }
      )
    );

    expect(tester.widget<Text>(find.byKey(textKey)).data, 'Back');

    // Unrecognized locale falls back to 'en'
    await tester.binding.setLocale('foo', 'BAR');
    await tester.pump();
    expect(tester.widget<Text>(find.byKey(textKey)).data, 'Back');

    // Spanish Bolivia locale, falls back to just 'es'
    await tester.binding.setLocale('es', 'BO');
    await tester.pump();
    expect(tester.widget<Text>(find.byKey(textKey)).data, 'Atrás');
  });

  testWidgets("Localizations.override widget tracks parent's locale", (WidgetTester tester) async {
    Widget buildLocaleFrame(Locale locale) {
      return buildFrame(
        locale: locale,
        supportedLocales: <Locale>[locale],
        buildContent: (BuildContext context) {
          return Localizations.override(
            context: context,
            child: Builder(
              builder: (BuildContext context) {
                // No MaterialLocalizations are defined for the first Localizations
                // ancestor, so we should get the values from the default one, i.e.
                // the one created by WidgetsApp via the LocalizationsDelegate
                // provided by MaterialApp.
                return Text(MaterialLocalizations.of(context).backButtonTooltip);
              },
            ),
          );
        },
      );
    }

    await tester.pumpWidget(buildLocaleFrame(const Locale('en', 'US')));
    expect(find.text('Back'), findsOneWidget);

    await tester.pumpWidget(buildLocaleFrame(const Locale('de', 'DE')));
    expect(find.text('Zurück'), findsOneWidget);

    await tester.pumpWidget(buildLocaleFrame(const Locale('zh', 'CN')));
    expect(find.text('返回'), findsOneWidget);
  });

  testWidgets('Localizations.override widget with hardwired locale', (WidgetTester tester) async {
    Widget buildLocaleFrame(Locale locale) {
      return buildFrame(
        locale: locale,
        buildContent: (BuildContext context) {
          return Localizations.override(
            context: context,
            locale: const Locale('en', 'US'),
            child: Builder(
              builder: (BuildContext context) {
                // No MaterialLocalizations are defined for the Localizations.override
                // ancestor, so we should get all values from the default one, i.e.
                // the one created by WidgetsApp via the LocalizationsDelegate
                // provided by MaterialApp.
                return Text(MaterialLocalizations.of(context).backButtonTooltip);
              },
            ),
          );
        },
      );
    }

    await tester.pumpWidget(buildLocaleFrame(const Locale('en', 'US')));
    expect(find.text('Back'), findsOneWidget);

    await tester.pumpWidget(buildLocaleFrame(const Locale('de', 'DE')));
    expect(find.text('Back'), findsOneWidget);

    await tester.pumpWidget(buildLocaleFrame(const Locale('zh', 'CN')));
    expect(find.text('Back'), findsOneWidget);
  });

  testWidgets('MaterialApp adds MaterialLocalizations for additional languages', (WidgetTester tester) async {
    final Key textKey = UniqueKey();

    await tester.pumpWidget(
      buildFrame(
        delegates: <FooMaterialLocalizationsDelegate>[
          const FooMaterialLocalizationsDelegate(supportedLanguage: 'fr', backButtonTooltip: 'FR'),
          const FooMaterialLocalizationsDelegate(supportedLanguage: 'de', backButtonTooltip: 'DE'),
        ],
        supportedLocales: const <Locale>[
          Locale('en'),
          Locale('fr'),
          Locale('de'),
        ],
        buildContent: (BuildContext context) {
          return Text(
            MaterialLocalizations.of(context).backButtonTooltip,
            key: textKey,
          );
        },
      )
    );

    expect(tester.widget<Text>(find.byKey(textKey)).data, 'Back');

    await tester.binding.setLocale('fr', 'CA');
    await tester.pump();
    expect(find.text('FR'), findsOneWidget);

    await tester.binding.setLocale('de', 'DE');
    await tester.pump();
    expect(find.text('DE'), findsOneWidget);
  });

  testWidgets('MaterialApp overrides MaterialLocalizations for all locales', (WidgetTester tester) async {
    final Key textKey = UniqueKey();

    await tester.pumpWidget(
      buildFrame(
        // Accept whatever locale we're given
        localeResolutionCallback: (Locale locale, Iterable<Locale> supportedLocales) => locale,
        delegates: <FooMaterialLocalizationsDelegate>[
          const FooMaterialLocalizationsDelegate(supportedLanguage: 'allLanguages'),
        ],
        buildContent: (BuildContext context) {
          // Should always be 'foo', no matter what the locale is
          return Text(
            MaterialLocalizations.of(context).backButtonTooltip,
            key: textKey,
          );
        },
      )
    );

    expect(tester.widget<Text>(find.byKey(textKey)).data, 'foo');

    await tester.binding.setLocale('zh', 'CN');
    await tester.pump();
    expect(find.text('foo'), findsOneWidget);

    await tester.binding.setLocale('de', 'DE');
    await tester.pump();
    expect(find.text('foo'), findsOneWidget);
  });

  testWidgets('MaterialApp overrides MaterialLocalizations for default locale', (WidgetTester tester) async {
    final Key textKey = UniqueKey();

    await tester.pumpWidget(
      buildFrame(
        delegates: <FooMaterialLocalizationsDelegate>[
          const FooMaterialLocalizationsDelegate(supportedLanguage: 'en'),
        ],
        // supportedLocales not specified, so all locales resolve to 'en'
        buildContent: (BuildContext context) {
          return Text(
            MaterialLocalizations.of(context).backButtonTooltip,
            key: textKey,
          );
        },
      )
    );

    // Unsupported locale '_' (the widget tester's default) resolves to 'en'.
    expect(tester.widget<Text>(find.byKey(textKey)).data, 'foo');

    // Unsupported locale 'zh' resolves to 'en'.
    await tester.binding.setLocale('zh', 'CN');
    await tester.pump();
    expect(find.text('foo'), findsOneWidget);

    // Unsupported locale 'de' resolves to 'en'.
    await tester.binding.setLocale('de', 'DE');
    await tester.pump();
    expect(find.text('foo'), findsOneWidget);
  });

  testWidgets('deprecated Android/Java locales are modernized', (WidgetTester tester) async {
    final Key textKey = UniqueKey();

    await tester.pumpWidget(
      buildFrame(
        supportedLocales: <Locale>[
          const Locale('en', 'US'),
          const Locale('he', 'IL'),
          const Locale('yi', 'IL'),
          const Locale('id', 'JV'),
        ],
        buildContent: (BuildContext context) {
          return Text(
            '${Localizations.localeOf(context)}',
            key: textKey,
          );
        },
      )
    );

    expect(tester.widget<Text>(find.byKey(textKey)).data, 'en_US');

    // Hebrew was iw (ISO-639) is he (ISO-639-1)
    await tester.binding.setLocale('iw', 'IL');
    await tester.pump();
    expect(tester.widget<Text>(find.byKey(textKey)).data, 'he_IL');

    // Yiddish was ji (ISO-639) is yi (ISO-639-1)
    await tester.binding.setLocale('ji', 'IL');
    await tester.pump();
    expect(tester.widget<Text>(find.byKey(textKey)).data, 'yi_IL');

    // Indonesian was in (ISO-639) is id (ISO-639-1)
    await tester.binding.setLocale('in', 'JV');
    await tester.pump();
    expect(tester.widget<Text>(find.byKey(textKey)).data, 'id_JV');
  });
}
