// Copyright 2013 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_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>[];
    late Map<String, dynamic> responses;
    late 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>[
          _isSignInMethodCall(),
          isMethodCall('signInSilently', arguments: null),
        ],
      );
    });

    test('signIn', () async {
      await googleSignIn.signIn();
      expect(googleSignIn.currentUser, isNotNull);
      expect(
        log,
        <Matcher>[
          _isSignInMethodCall(),
          isMethodCall('signIn', arguments: null),
        ],
      );
    });

    test('signIn prioritize clientId parameter when available', () async {
      final fakeClientId = 'fakeClientId';
      googleSignIn = GoogleSignIn(clientId: fakeClientId);
      await googleSignIn.signIn();
      expect(googleSignIn.currentUser, isNotNull);
      expect(
        log,
        <Matcher>[
          isMethodCall('init', arguments: <String, dynamic>{
            'signInOption': 'SignInOption.standard',
            'scopes': <String>[],
            'hostedDomain': null,
            'clientId': fakeClientId,
          }),
          isMethodCall('signIn', arguments: null),
        ],
      );
    });

    test('signOut', () async {
      await googleSignIn.signOut();
      expect(googleSignIn.currentUser, isNull);
      expect(log, <Matcher>[
        _isSignInMethodCall(),
        isMethodCall('signOut', arguments: null),
      ]);
    });

    test('disconnect; null response', () async {
      await googleSignIn.disconnect();
      expect(googleSignIn.currentUser, isNull);
      expect(
        log,
        <Matcher>[
          _isSignInMethodCall(),
          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>[
          _isSignInMethodCall(),
          isMethodCall('disconnect', arguments: null),
        ],
      );
    });

    test('isSignedIn', () async {
      final bool result = await googleSignIn.isSignedIn();
      expect(result, isTrue);
      expect(log, <Matcher>[
        _isSignInMethodCall(),
        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>[
          _isSignInMethodCall(),
          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>[
          _isSignInMethodCall(),
          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>[
          _isSignInMethodCall(),
          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>[
          _isSignInMethodCall(),
          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>[
          _isSignInMethodCall(),
          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>[
          _isSignInMethodCall(),
          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('signInSilently allows re-authentication to be requested', () async {
      await googleSignIn.signInSilently();
      expect(googleSignIn.currentUser, isNotNull);

      await googleSignIn.signInSilently(reAuthenticate: true);

      expect(
        log,
        <Matcher>[
          _isSignInMethodCall(),
          isMethodCall('signInSilently', arguments: null),
          isMethodCall('signInSilently', arguments: null),
        ],
      );
    });

    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>[
          _isSignInMethodCall(),
          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>[
          _isSignInMethodCall(signInOption: 'SignInOption.games'),
          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>[
          _isSignInMethodCall(),
          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",
    );

    late GoogleSignIn googleSignIn;

    setUp(() {
      final MethodChannelGoogleSignIn platformInstance =
          GoogleSignInPlatform.instance as MethodChannelGoogleSignIn;
      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);
    });
  });
}

Matcher _isSignInMethodCall({String signInOption = 'SignInOption.standard'}) {
  return isMethodCall('init', arguments: <String, dynamic>{
    'signInOption': signInOption,
    'scopes': <String>[],
    'hostedDomain': null,
    'clientId': null,
  });
}
