// 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.

// @dart = 2.8

import 'dart:async';

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:google_sign_in_platform_interface/google_sign_in_platform_interface.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:google_sign_in/testing.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  group('GoogleSignIn', () {
    const MethodChannel channel = MethodChannel(
      'plugins.flutter.io/google_sign_in',
    );

    const Map<String, String> kUserData = <String, String>{
      "email": "john.doe@gmail.com",
      "id": "8162538176523816253123",
      "photoUrl": "https://lh5.googleusercontent.com/photo.jpg",
      "displayName": "John Doe",
    };

    const Map<String, dynamic> kDefaultResponses = <String, dynamic>{
      'init': null,
      'signInSilently': kUserData,
      'signIn': kUserData,
      'signOut': null,
      'disconnect': null,
      'isSignedIn': true,
      'requestScopes': true,
      'getTokens': <dynamic, dynamic>{
        'idToken': '123',
        'accessToken': '456',
        'serverAuthCode': '789',
      },
    };

    final List<MethodCall> log = <MethodCall>[];
    Map<String, dynamic> responses;
    GoogleSignIn googleSignIn;

    setUp(() {
      responses = Map<String, dynamic>.from(kDefaultResponses);
      channel.setMockMethodCallHandler((MethodCall methodCall) {
        log.add(methodCall);
        final dynamic response = responses[methodCall.method];
        if (response != null && response is Exception) {
          return Future<dynamic>.error('$response');
        }
        return Future<dynamic>.value(response);
      });
      googleSignIn = GoogleSignIn();
      log.clear();
    });

    test('signInSilently', () async {
      await googleSignIn.signInSilently();
      expect(googleSignIn.currentUser, isNotNull);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.standard',
            'scopes': <String>[],
            'hostedDomain': null,
          }),
          isMethodCall('signInSilently', arguments: null),
        ],
      );
    });

    test('signIn', () async {
      await googleSignIn.signIn();
      expect(googleSignIn.currentUser, isNotNull);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.standard',
            'scopes': <String>[],
            'hostedDomain': null,
          }),
          isMethodCall('signIn', arguments: null),
        ],
      );
    });

    test('signOut', () async {
      await googleSignIn.signOut();
      expect(googleSignIn.currentUser, isNull);
      expect(log, <Matcher>[
        isMethodCall('init', arguments: <String, dynamic>{
          'signInOption': 'SignInOption.standard',
          'scopes': <String>[],
          'hostedDomain': null,
        }),
        isMethodCall('signOut', arguments: null),
      ]);
    });

    test('disconnect; null response', () async {
      await googleSignIn.disconnect();
      expect(googleSignIn.currentUser, isNull);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.standard',
            'scopes': <String>[],
            'hostedDomain': null,
          }),
          isMethodCall('disconnect', arguments: null),
        ],
      );
    });

    test('disconnect; empty response as on iOS', () async {
      responses['disconnect'] = <String, dynamic>{};
      await googleSignIn.disconnect();
      expect(googleSignIn.currentUser, isNull);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.standard',
            'scopes': <String>[],
            'hostedDomain': null,
          }),
          isMethodCall('disconnect', arguments: null),
        ],
      );
    });

    test('isSignedIn', () async {
      final bool result = await googleSignIn.isSignedIn();
      expect(result, isTrue);
      expect(log, <Matcher>[
        isMethodCall('init', arguments: <String, dynamic>{
          'signInOption': 'SignInOption.standard',
          'scopes': <String>[],
          'hostedDomain': null,
        }),
        isMethodCall('isSignedIn', arguments: null),
      ]);
    });

    test('signIn works even if a previous call throws error in other zone',
        () async {
      responses['signInSilently'] = Exception('Not a user');
      await runZonedGuarded(() async {
        expect(await googleSignIn.signInSilently(), isNull);
      }, (Object e, StackTrace st) {});
      expect(await googleSignIn.signIn(), isNotNull);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.standard',
            'scopes': <String>[],
            'hostedDomain': null,
          }),
          isMethodCall('signInSilently', arguments: null),
          isMethodCall('signIn', arguments: null),
        ],
      );
    });

    test('concurrent calls of the same method trigger sign in once', () async {
      final List<Future<GoogleSignInAccount>> futures =
          <Future<GoogleSignInAccount>>[
        googleSignIn.signInSilently(),
        googleSignIn.signInSilently(),
      ];
      expect(futures.first, isNot(futures.last),
          reason: 'Must return new Future');
      final List<GoogleSignInAccount> users = await Future.wait(futures);
      expect(googleSignIn.currentUser, isNotNull);
      expect(users, <GoogleSignInAccount>[
        googleSignIn.currentUser,
        googleSignIn.currentUser
      ]);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.standard',
            'scopes': <String>[],
            'hostedDomain': null,
          }),
          isMethodCall('signInSilently', arguments: null),
        ],
      );
    });

    test('can sign in after previously failed attempt', () async {
      responses['signInSilently'] = Exception('Not a user');
      expect(await googleSignIn.signInSilently(), isNull);
      expect(await googleSignIn.signIn(), isNotNull);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.standard',
            'scopes': <String>[],
            'hostedDomain': null,
          }),
          isMethodCall('signInSilently', arguments: null),
          isMethodCall('signIn', arguments: null),
        ],
      );
    });

    test('concurrent calls of different signIn methods', () async {
      final List<Future<GoogleSignInAccount>> futures =
          <Future<GoogleSignInAccount>>[
        googleSignIn.signInSilently(),
        googleSignIn.signIn(),
      ];
      expect(futures.first, isNot(futures.last));
      final List<GoogleSignInAccount> users = await Future.wait(futures);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.standard',
            'scopes': <String>[],
            'hostedDomain': null,
          }),
          isMethodCall('signInSilently', arguments: null),
        ],
      );
      expect(users.first, users.last, reason: 'Must return the same user');
      expect(googleSignIn.currentUser, users.last);
    });

    test('can sign in after aborted flow', () async {
      responses['signIn'] = null;
      expect(await googleSignIn.signIn(), isNull);
      responses['signIn'] = kUserData;
      expect(await googleSignIn.signIn(), isNotNull);
    });

    test('signOut/disconnect methods always trigger native calls', () async {
      final List<Future<GoogleSignInAccount>> futures =
          <Future<GoogleSignInAccount>>[
        googleSignIn.signOut(),
        googleSignIn.signOut(),
        googleSignIn.disconnect(),
        googleSignIn.disconnect(),
      ];
      await Future.wait(futures);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.standard',
            'scopes': <String>[],
            'hostedDomain': null,
          }),
          isMethodCall('signOut', arguments: null),
          isMethodCall('signOut', arguments: null),
          isMethodCall('disconnect', arguments: null),
          isMethodCall('disconnect', arguments: null),
        ],
      );
    });

    test('queue of many concurrent calls', () async {
      final List<Future<GoogleSignInAccount>> futures =
          <Future<GoogleSignInAccount>>[
        googleSignIn.signInSilently(),
        googleSignIn.signOut(),
        googleSignIn.signIn(),
        googleSignIn.disconnect(),
      ];
      await Future.wait(futures);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.standard',
            'scopes': <String>[],
            'hostedDomain': null,
          }),
          isMethodCall('signInSilently', arguments: null),
          isMethodCall('signOut', arguments: null),
          isMethodCall('signIn', arguments: null),
          isMethodCall('disconnect', arguments: null),
        ],
      );
    });

    test('signInSilently suppresses errors by default', () async {
      channel.setMockMethodCallHandler((MethodCall methodCall) {
        throw "I am an error";
      });
      expect(await googleSignIn.signInSilently(), isNull); // should not throw
    });

    test('signInSilently forwards errors', () async {
      channel.setMockMethodCallHandler((MethodCall methodCall) {
        throw "I am an error";
      });
      expect(googleSignIn.signInSilently(suppressErrors: false),
          throwsA(isInstanceOf<PlatformException>()));
    });

    test('can sign in after init failed before', () async {
      int initCount = 0;
      channel.setMockMethodCallHandler((MethodCall methodCall) {
        if (methodCall.method == 'init') {
          initCount++;
          if (initCount == 1) {
            throw "First init fails";
          }
        }
        return Future<dynamic>.value(responses[methodCall.method]);
      });
      expect(googleSignIn.signIn(), throwsA(isInstanceOf<PlatformException>()));
      expect(await googleSignIn.signIn(), isNotNull);
    });

    test('created with standard factory uses correct options', () async {
      googleSignIn = GoogleSignIn.standard();

      await googleSignIn.signInSilently();
      expect(googleSignIn.currentUser, isNotNull);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.standard',
            'scopes': <String>[],
            'hostedDomain': null,
          }),
          isMethodCall('signInSilently', arguments: null),
        ],
      );
    });

    test('created with defaultGamesSignIn factory uses correct options',
        () async {
      googleSignIn = GoogleSignIn.games();

      await googleSignIn.signInSilently();
      expect(googleSignIn.currentUser, isNotNull);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.games',
            'scopes': <String>[],
            'hostedDomain': null,
          }),
          isMethodCall('signInSilently', arguments: null),
        ],
      );
    });

    test('authentication', () async {
      await googleSignIn.signIn();
      log.clear();

      final GoogleSignInAccount user = googleSignIn.currentUser;
      final GoogleSignInAuthentication auth = await user.authentication;

      expect(auth.accessToken, '456');
      expect(auth.idToken, '123');
      expect(auth.serverAuthCode, '789');
      expect(
        log,
        <Matcher>[
          isMethodCall('getTokens', arguments: <String, dynamic>{
            'email': 'john.doe@gmail.com',
            'shouldRecoverAuth': true,
          }),
        ],
      );
    });

    test('requestScopes returns true once new scope is granted', () async {
      await googleSignIn.signIn();
      final result = await googleSignIn.requestScopes(['testScope']);

      expect(result, isTrue);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.standard',
            'scopes': <String>[],
            'hostedDomain': null,
          }),
          isMethodCall('signIn', arguments: null),
          isMethodCall('requestScopes', arguments: <String, dynamic>{
            'scopes': ['testScope'],
          }),
        ],
      );
    });
  });

  group('GoogleSignIn with fake backend', () {
    const FakeUser kUserData = FakeUser(
      id: "8162538176523816253123",
      displayName: "John Doe",
      email: "john.doe@gmail.com",
      photoUrl: "https://lh5.googleusercontent.com/photo.jpg",
    );

    GoogleSignIn googleSignIn;

    setUp(() {
      final MethodChannelGoogleSignIn platformInstance =
          GoogleSignInPlatform.instance;
      platformInstance.channel.setMockMethodCallHandler(
          (FakeSignInBackend()..user = kUserData).handleMethodCall);
      googleSignIn = GoogleSignIn();
    });

    test('user starts as null', () async {
      expect(googleSignIn.currentUser, isNull);
    });

    test('can sign in and sign out', () async {
      await googleSignIn.signIn();

      final GoogleSignInAccount user = googleSignIn.currentUser;

      expect(user.displayName, equals(kUserData.displayName));
      expect(user.email, equals(kUserData.email));
      expect(user.id, equals(kUserData.id));
      expect(user.photoUrl, equals(kUserData.photoUrl));

      await googleSignIn.disconnect();
      expect(googleSignIn.currentUser, isNull);
    });

    test('disconnect when signout already succeeds', () async {
      await googleSignIn.disconnect();
      expect(googleSignIn.currentUser, isNull);
    });
  });
}
