// Copyright 2019 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/material.dart';
import 'package:flutter_app_icons/flutter_app_icons_platform_interface.dart';
import 'package:flutter_dashboard/build_dashboard_page.dart';
import 'package:flutter_dashboard/model/branch.pb.dart';
import 'package:flutter_dashboard/model/build_status_response.pb.dart';
import 'package:flutter_dashboard/model/commit_status.pb.dart';
import 'package:flutter_dashboard/service/cocoon.dart';
import 'package:flutter_dashboard/service/dev_cocoon.dart';
import 'package:flutter_dashboard/service/google_authentication.dart';
import 'package:flutter_dashboard/state/build.dart';
import 'package:flutter_dashboard/widgets/error_brook_watcher.dart';
import 'package:flutter_dashboard/widgets/sign_in_button.dart';
import 'package:flutter_dashboard/widgets/state_provider.dart';
import 'package:flutter_dashboard/widgets/task_box.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';

import 'utils/fake_build.dart';
import 'utils/fake_flutter_app_icons.dart';
import 'utils/fake_google_account.dart';
import 'utils/golden.dart';
import 'utils/mocks.dart';
import 'utils/output.dart';
import 'utils/task_icons.dart';

void main() {
  late MockGoogleSignInService fakeAuthService;

  final Type dropdownButtonType = DropdownButton<String>(
    onChanged: (_) {},
    items: const <DropdownMenuItem<String>>[],
  ).runtimeType;

  void configureView(TestFlutterView view) {
    // device pixel ratio of 1.0 works well on web app and emulator
    // If not set, flutter test uses a Pixel 4 device pixel ratio of roughly 2.75, which doesn't quite work
    // I am using the default settings of Pixel 4 in this test, as referenced in the link below
    // https://android.googlesource.com/platform/external/qemu/+/b5b78438ae9ff3b90aafdab0f4f25585affc22fb/android/avd/hardware-properties.ini
    view.devicePixelRatio = 1.0;
    view.physicalSize = const Size(1080, 2280);
    addTearDown(view.reset);
  }

  setUp(() {
    fakeAuthService = MockGoogleSignInService();
    when(fakeAuthService.isAuthenticated).thenAnswer((_) => Future<bool>.value(true));
    when(fakeAuthService.user).thenReturn(FakeGoogleSignInAccount());

    FlutterAppIconsPlatform.instance = FakeFlutterAppIcons();
  });

  testWidgets('shows sign in button', (WidgetTester tester) async {
    configureView(tester.view);
    final MockCocoonService fakeCocoonService = MockCocoonService();
    throwOnMissingStub(fakeCocoonService);
    when(fakeCocoonService.fetchFlutterBranches()).thenAnswer((_) => Completer<CocoonResponse<List<Branch>>>().future);
    when(fakeCocoonService.fetchRepos()).thenAnswer((_) => Completer<CocoonResponse<List<String>>>().future);
    when(
      fakeCocoonService.fetchCommitStatuses(
        branch: anyNamed('branch'),
        repo: anyNamed('repo'),
      ),
    ).thenAnswer((_) => Completer<CocoonResponse<List<CommitStatus>>>().future);
    when(
      fakeCocoonService.fetchTreeBuildStatus(
        branch: anyNamed('branch'),
        repo: anyNamed('repo'),
      ),
    ).thenAnswer((_) => Completer<CocoonResponse<BuildStatusResponse>>().future);

    final BuildState buildState = BuildState(
      cocoonService: fakeCocoonService,
      authService: fakeAuthService,
    );

    await tester.pumpWidget(
      MaterialApp(
        home: ValueProvider<BuildState>(
          value: buildState,
          child: ValueProvider<GoogleSignInService>(
            value: buildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );
    expect(find.byType(SignInButton), findsOneWidget);

    await tester.pumpWidget(Container());
    buildState.dispose();
  });

  testWidgets('shows settings button', (WidgetTester tester) async {
    configureView(tester.view);
    final BuildState fakeBuildState = FakeBuildState()..authService = fakeAuthService;

    await tester.pumpWidget(
      MaterialApp(
        home: ValueProvider<BuildState>(
          value: fakeBuildState,
          child: ValueProvider<GoogleSignInService>(
            value: fakeBuildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    expect(find.byIcon(Icons.settings), findsOneWidget);
  });

  testWidgets('shows file a bug button', (WidgetTester tester) async {
    configureView(tester.view);
    final BuildState fakeBuildState = FakeBuildState()..authService = fakeAuthService;

    await tester.pumpWidget(
      MaterialApp(
        home: ValueProvider<BuildState>(
          value: fakeBuildState,
          child: ValueProvider<GoogleSignInService>(
            value: fakeBuildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    expect(find.byIcon(Icons.bug_report), findsOneWidget);
  });

  testWidgets('shows key button & legend', (WidgetTester tester) async {
    configureView(tester.view);
    final BuildState fakeBuildState = FakeBuildState()..authService = fakeAuthService;

    await tester.pumpWidget(
      MaterialApp(
        home: ValueProvider<BuildState>(
          value: fakeBuildState,
          child: ValueProvider<GoogleSignInService>(
            value: fakeBuildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    expect(find.byIcon(Icons.info_outline), findsOneWidget);

    await tester.tap(find.byIcon(Icons.info_outline));
    await tester.pump();

    for (final String status in TaskBox.statusColor.keys) {
      expect(find.text(status), findsOneWidget);
    }
    expect(find.text('Flaky'), findsOneWidget);
    expect(find.text('Ran more than once'), findsOneWidget);
  });

  testWidgets('shows branch and repo dropdown button when screen is decently large', (WidgetTester tester) async {
    configureView(tester.view);
    final BuildState fakeBuildState = FakeBuildState()..authService = fakeAuthService;

    await tester.pumpWidget(
      MaterialApp(
        home: ValueProvider<BuildState>(
          value: fakeBuildState,
          child: ValueProvider<GoogleSignInService>(
            value: fakeBuildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    expect(find.byType(dropdownButtonType), findsNWidgets(2));

    expect(find.text('repo: '), findsOneWidget);
    expect((tester.widget(find.byKey(const Key('repo dropdown'))) as DropdownButton).value, equals('flutter'));

    expect(find.text('branch: '), findsOneWidget);
    expect((tester.widget(find.byKey(const Key('branch dropdown'))) as DropdownButton).value, equals('master'));
  });

  testWidgets('shows vacuum github commits button', (WidgetTester tester) async {
    configureView(tester.view);
    final BuildState fakeBuildState = FakeBuildState()..authService = fakeAuthService;

    await tester.pumpWidget(
      MaterialApp(
        home: ValueProvider<BuildState>(
          value: fakeBuildState,
          child: ValueProvider<GoogleSignInService>(
            value: fakeBuildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    // Open settings overlay
    await tester.tap(find.byIcon(Icons.settings));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1)); // Finish the menu animation.

    expect(find.text('Vacuum GitHub Commits'), findsOneWidget);
  });

  testWidgets('shows loading when fetch tree status is null', (WidgetTester tester) async {
    configureView(tester.view);
    final BuildState fakeBuildState = FakeBuildState()
      ..isTreeBuilding = null
      ..authService = fakeAuthService;

    await tester.pumpWidget(
      MaterialApp(
        home: ValueProvider<BuildState>(
          value: fakeBuildState,
          child: ValueProvider<GoogleSignInService>(
            value: fakeBuildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    expect(find.text('Loading...'), findsOneWidget);

    final AppBar appbarWidget = find.byType(AppBar).evaluate().first.widget as AppBar;
    expect(appbarWidget.backgroundColor, Colors.grey[850]);
    expect(tester, meetsGuideline(textContrastGuideline));
  });

  testWidgets('shows loading when fetch tree status is null, dark mode', (WidgetTester tester) async {
    configureView(tester.view);
    final BuildState fakeBuildState = FakeBuildState()
      ..isTreeBuilding = null
      ..authService = fakeAuthService;

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData.dark(),
        home: ValueProvider<BuildState>(
          value: fakeBuildState,
          child: ValueProvider<GoogleSignInService>(
            value: fakeBuildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    expect(find.text('Loading...'), findsOneWidget);

    final AppBar appbarWidget = find.byType(AppBar).evaluate().first.widget as AppBar;
    expect(appbarWidget.backgroundColor, Colors.grey[850]);
    expect(tester, meetsGuideline(textContrastGuideline));
  });

  testWidgets('shows tree closed when fetch tree status is false', (WidgetTester tester) async {
    configureView(tester.view);
    final BuildState fakeBuildState = FakeBuildState()
      ..isTreeBuilding = false
      ..authService = fakeAuthService;

    await tester.pumpWidget(
      MaterialApp(
        home: ValueProvider<BuildState>(
          value: fakeBuildState,
          child: ValueProvider<GoogleSignInService>(
            value: fakeBuildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    // Verify the "Tree is Closed" message is wrapped in a [Tooltip].
    final Finder tooltipFinder = find.byWidgetPredicate((Widget widget) {
      return widget is Tooltip && (widget.message?.contains('Tree is Closed') ?? false);
    });
    expect(tooltipFinder, findsOneWidget);

    final AppBar appbarWidget = find.byType(AppBar).evaluate().first.widget as AppBar;
    expect(appbarWidget.backgroundColor, Colors.red);
    expect(tester, meetsGuideline(textContrastGuideline));
  });

  testWidgets('shows tree closed when fetch tree status is false, dark mode', (WidgetTester tester) async {
    configureView(tester.view);
    final BuildState fakeBuildState = FakeBuildState()
      ..isTreeBuilding = false
      ..authService = fakeAuthService;

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData.dark(),
        home: ValueProvider<BuildState>(
          value: fakeBuildState,
          child: ValueProvider<GoogleSignInService>(
            value: fakeBuildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    // Verify the "Tree is Closed" message is wrapped in a [Tooltip].
    final Finder tooltipFinder = find.byWidgetPredicate((Widget widget) {
      return widget is Tooltip && (widget.message?.contains('Tree is Closed') ?? false);
    });
    expect(tooltipFinder, findsOneWidget);

    final AppBar appbarWidget = find.byType(AppBar).evaluate().first.widget as AppBar;
    expect(appbarWidget.backgroundColor, Colors.red[800]);
    expect(tester, meetsGuideline(textContrastGuideline));
  });

  testWidgets('shows tree open when fetch tree status is true', (WidgetTester tester) async {
    configureView(tester.view);
    final BuildState fakeBuildState = FakeBuildState()
      ..isTreeBuilding = true
      ..authService = fakeAuthService;

    await tester.pumpWidget(
      MaterialApp(
        home: ValueProvider<BuildState>(
          value: fakeBuildState,
          child: ValueProvider<GoogleSignInService>(
            value: fakeBuildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    expect(find.text('Tree is Open'), findsOneWidget);

    final AppBar appbarWidget = find.byType(AppBar).evaluate().first.widget as AppBar;
    expect(appbarWidget.backgroundColor, Colors.green);
    expect(tester, meetsGuideline(textContrastGuideline));
  });

  testWidgets('shows tree open when fetch tree status is true, dark mode', (WidgetTester tester) async {
    configureView(tester.view);
    final BuildState fakeBuildState = FakeBuildState()
      ..isTreeBuilding = true
      ..authService = fakeAuthService;

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData.dark(),
        home: ValueProvider<BuildState>(
          value: fakeBuildState,
          child: ValueProvider<GoogleSignInService>(
            value: fakeBuildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    expect(find.text('Tree is Open'), findsOneWidget);

    final AppBar appbarWidget = find.byType(AppBar).evaluate().first.widget as AppBar;
    expect(appbarWidget.backgroundColor, Colors.green[800]);
    expect(tester, meetsGuideline(textContrastGuideline));
  });

  testWidgets('show error snackbar when error occurs', (WidgetTester tester) async {
    configureView(tester.view);
    String? lastError;
    final FakeBuildState buildState = FakeBuildState()
      ..errors.addListener((String message) => lastError = message)
      ..authService = fakeAuthService;

    await tester.pumpWidget(
      MaterialApp(
        home: ValueProvider<BuildState>(
          value: buildState,
          child: ValueProvider<GoogleSignInService>(
            value: buildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    expect(lastError, isNull);

    // propagate the error message
    await checkOutput(
      block: () async {
        buildState.errors.send('ERROR');
      },
      output: <String>[
        'ERROR',
      ],
    );
    await tester.pump();

    await tester.pump(const Duration(milliseconds: 750)); // open animation for snackbar

    expect(find.text(lastError!), findsOneWidget);

    // Snackbar message should go away after its duration
    await tester.pump(ErrorBrookWatcher.errorSnackbarDuration); // wait the duration
    await tester.pump(); // schedule animation
    await tester.pump(const Duration(milliseconds: 1500)); // close animation

    expect(find.text(lastError!), findsNothing);
  });

  testWidgets('TaskGridContainer with default Settings property sheet', (WidgetTester tester) async {
    configureView(tester.view);
    await precacheTaskIcons(tester);
    final BuildState buildState = BuildState(
      cocoonService: DevelopmentCocoonService(DateTime.utc(2020)),
      authService: fakeAuthService,
    );
    void listener1() {}
    buildState.addListener(listener1);

    await tester.pumpWidget(
      MaterialApp(
        home: ValueProvider<BuildState>(
          value: buildState,
          child: ValueProvider<GoogleSignInService>(
            value: buildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    await tester.tap(find.byIcon(Icons.settings));
    await tester.pump();

    await expectGoldenMatches(find.byType(BuildDashboardPage), 'build_dashboard.defaultPropertySheet.png');
    expect(tester, meetsGuideline(textContrastGuideline));

    await tester.pumpWidget(Container());
    buildState.dispose();
  });

  testWidgets('TaskGridContainer with default Settings property sheet, dark mode', (WidgetTester tester) async {
    configureView(tester.view);
    await precacheTaskIcons(tester);
    final BuildState buildState = BuildState(
      cocoonService: DevelopmentCocoonService(DateTime.utc(2020)),
      authService: fakeAuthService,
    );
    void listener1() {}
    buildState.addListener(listener1);

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData.dark(),
        home: ValueProvider<BuildState>(
          value: buildState,
          child: ValueProvider<GoogleSignInService>(
            value: buildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    await tester.tap(find.byIcon(Icons.settings));
    await tester.pump();

    await expectGoldenMatches(find.byType(BuildDashboardPage), 'build_dashboard.defaultPropertySheet.dark.png');
    expect(tester, meetsGuideline(textContrastGuideline));

    await tester.pumpWidget(Container());
    buildState.dispose();
  });

  testWidgets('ensure smooth transition between invalid states', (WidgetTester tester) async {
    configureView(tester.view);
    final BuildState fakeBuildState = FakeBuildState()..authService = fakeAuthService;
    BuildDashboardPage controlledBuildDashboardPage = const BuildDashboardPage(
      queryParameters: {
        'repo': 'flutter',
        'branch': 'flutter-release',
      },
    );

    await tester.pumpWidget(
      MaterialApp(
        home: ValueProvider<BuildState>(
          value: fakeBuildState,
          child: ValueProvider<GoogleSignInService>(
            value: fakeBuildState.authService,
            child: controlledBuildDashboardPage,
          ),
        ),
      ),
    );

    expect(find.byType(dropdownButtonType), findsNWidgets(2));
    // simulate a url request, which retriggers a rebuild of the widget
    controlledBuildDashboardPage = const BuildDashboardPage(
      queryParameters: {
        'repo': 'engine',
      },
    );
    expect(
      (tester.widget(find.byKey(const Key('branch dropdown'))) as DropdownButton).value,
      equals('flutter-release'),
    ); //invalid state: engine + flutter-release
    await tester.pump(); //an invalid state will generate delayed network responses

    //if a delayed network request come in, from a previous invalid state: cocoon + engine - release, no exceptions should be raised
    controlledBuildDashboardPage = const BuildDashboardPage(
      queryParameters: {
        'repo': 'cocoon',
        'branch': 'engine-release',
      },
    );
  });

  testWidgets('shows branch and repo dropdown button in settings when screen is small', (WidgetTester tester) async {
    tester.view.physicalSize = const Size(500, 500);
    tester.view.devicePixelRatio = 1.0;
    addTearDown(tester.view.reset);
    final BuildState fakeBuildState = FakeBuildState()..authService = fakeAuthService;

    await tester.pumpWidget(
      MaterialApp(
        home: ValueProvider<BuildState>(
          value: fakeBuildState,
          child: ValueProvider<GoogleSignInService>(
            value: fakeBuildState.authService,
            child: const BuildDashboardPage(),
          ),
        ),
      ),
    );

    expect(find.byType(dropdownButtonType), findsNothing);

    await tester.tap(find.byIcon(Icons.settings));
    await tester.pump();

    expect(find.byType(dropdownButtonType), findsNWidgets(2));
  });
}
