// 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/services.dart';
import 'package:flutter_test/flutter_test.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,
      'getTokens': <dynamic, dynamic>{
        'idToken': '123',
        'accessToken': '456',
      },
    };

    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 runZoned(() async {
        expect(await googleSignIn.signInSilently(), isNull);
      }, onError: (dynamic e, dynamic 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(
        log,
        <Matcher>[
          isMethodCall('getTokens', arguments: <String, dynamic>{
            'email': 'john.doe@gmail.com',
            'shouldRecoverAuth': true,
          }),
        ],
      );
    });
  });

  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(() {
      GoogleSignIn.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);
    });
  });
}
