// 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_test/flutter_test.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:google_sign_in_platform_interface/google_sign_in_platform_interface.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';

import 'google_sign_in_test.mocks.dart';

@GenerateMocks(<Type>[GoogleSignInPlatform])
void main() {
  late MockGoogleSignInPlatform mockPlatform;

  group('GoogleSignIn', () {
    final GoogleSignInUserData kDefaultUser = GoogleSignInUserData(
        email: 'john.doe@gmail.com',
        id: '8162538176523816253123',
        photoUrl: 'https://lh5.googleusercontent.com/photo.jpg',
        displayName: 'John Doe',
        serverAuthCode: '789');

    setUp(() {
      mockPlatform = MockGoogleSignInPlatform();
      when(mockPlatform.isMock).thenReturn(true);
      when(mockPlatform.signInSilently())
          .thenAnswer((Invocation _) async => kDefaultUser);
      when(mockPlatform.signIn())
          .thenAnswer((Invocation _) async => kDefaultUser);

      GoogleSignInPlatform.instance = mockPlatform;
    });

    test('signInSilently', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();

      await googleSignIn.signInSilently();

      expect(googleSignIn.currentUser, isNotNull);
      _verifyInit(mockPlatform);
      verify(mockPlatform.signInSilently());
    });

    test('signIn', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();

      await googleSignIn.signIn();

      expect(googleSignIn.currentUser, isNotNull);
      _verifyInit(mockPlatform);
      verify(mockPlatform.signIn());
    });

    test('signIn prioritize clientId parameter when available', () async {
      const String fakeClientId = 'fakeClientId';
      final GoogleSignIn googleSignIn = GoogleSignIn(clientId: fakeClientId);

      await googleSignIn.signIn();

      _verifyInit(mockPlatform, clientId: fakeClientId);
      verify(mockPlatform.signIn());
    });

    test('signOut', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();

      await googleSignIn.signOut();

      _verifyInit(mockPlatform);
      verify(mockPlatform.signOut());
    });

    test('disconnect; null response', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();

      await googleSignIn.disconnect();

      expect(googleSignIn.currentUser, isNull);
      _verifyInit(mockPlatform);
      verify(mockPlatform.disconnect());
    });

    test('isSignedIn', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();
      when(mockPlatform.isSignedIn()).thenAnswer((Invocation _) async => true);

      final bool result = await googleSignIn.isSignedIn();

      expect(result, isTrue);
      _verifyInit(mockPlatform);
      verify(mockPlatform.isSignedIn());
    });

    test('signIn works even if a previous call throws error in other zone',
        () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();

      when(mockPlatform.signInSilently()).thenThrow(Exception('Not a user'));
      await runZonedGuarded(() async {
        expect(await googleSignIn.signInSilently(), isNull);
      }, (Object e, StackTrace st) {});
      expect(await googleSignIn.signIn(), isNotNull);
      _verifyInit(mockPlatform);
      verify(mockPlatform.signInSilently());
      verify(mockPlatform.signIn());
    });

    test('concurrent calls of the same method trigger sign in once', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();
      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
      ]);
      _verifyInit(mockPlatform);
      verify(mockPlatform.signInSilently()).called(1);
    });

    test('can sign in after previously failed attempt', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();
      when(mockPlatform.signInSilently()).thenThrow(Exception('Not a user'));

      expect(await googleSignIn.signInSilently(), isNull);
      expect(await googleSignIn.signIn(), isNotNull);

      _verifyInit(mockPlatform);
      verify(mockPlatform.signInSilently());
      verify(mockPlatform.signIn());
    });

    test('concurrent calls of different signIn methods', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();
      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(users.first, users.last, reason: 'Must return the same user');
      expect(googleSignIn.currentUser, users.last);
      _verifyInit(mockPlatform);
      verify(mockPlatform.signInSilently());
      verifyNever(mockPlatform.signIn());
    });

    test('can sign in after aborted flow', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();

      when(mockPlatform.signIn()).thenAnswer((Invocation _) async => null);
      expect(await googleSignIn.signIn(), isNull);

      when(mockPlatform.signIn())
          .thenAnswer((Invocation _) async => kDefaultUser);
      expect(await googleSignIn.signIn(), isNotNull);
    });

    test('signOut/disconnect methods always trigger native calls', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();
      final List<Future<GoogleSignInAccount?>> futures =
          <Future<GoogleSignInAccount?>>[
        googleSignIn.signOut(),
        googleSignIn.signOut(),
        googleSignIn.disconnect(),
        googleSignIn.disconnect(),
      ];

      await Future.wait(futures);

      _verifyInit(mockPlatform);
      verify(mockPlatform.signOut()).called(2);
      verify(mockPlatform.disconnect()).called(2);
    });

    test('queue of many concurrent calls', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();
      final List<Future<GoogleSignInAccount?>> futures =
          <Future<GoogleSignInAccount?>>[
        googleSignIn.signInSilently(),
        googleSignIn.signOut(),
        googleSignIn.signIn(),
        googleSignIn.disconnect(),
      ];

      await Future.wait(futures);

      _verifyInit(mockPlatform);
      verifyInOrder(<Object>[
        mockPlatform.signInSilently(),
        mockPlatform.signOut(),
        mockPlatform.signIn(),
        mockPlatform.disconnect(),
      ]);
    });

    test('signInSilently suppresses errors by default', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();
      when(mockPlatform.signInSilently()).thenThrow(Exception('I am an error'));
      expect(await googleSignIn.signInSilently(), isNull); // should not throw
    });

    test('signInSilently forwards exceptions', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();
      when(mockPlatform.signInSilently()).thenThrow(Exception('I am an error'));
      expect(googleSignIn.signInSilently(suppressErrors: false),
          throwsA(isInstanceOf<Exception>()));
    });

    test('signInSilently allows re-authentication to be requested', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();
      await googleSignIn.signInSilently();
      expect(googleSignIn.currentUser, isNotNull);

      await googleSignIn.signInSilently(reAuthenticate: true);

      _verifyInit(mockPlatform);
      verify(mockPlatform.signInSilently()).called(2);
    });

    test('can sign in after init failed before', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();

      when(mockPlatform.init()).thenThrow(Exception('First init fails'));
      expect(googleSignIn.signIn(), throwsA(isInstanceOf<Exception>()));

      when(mockPlatform.init()).thenAnswer((Invocation _) async {});
      expect(await googleSignIn.signIn(), isNotNull);
    });

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

      await googleSignIn.signInSilently();
      expect(googleSignIn.currentUser, isNotNull);
      _verifyInit(mockPlatform);
      verify(mockPlatform.signInSilently());
    });

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

      await googleSignIn.signInSilently();
      expect(googleSignIn.currentUser, isNotNull);
      _verifyInit(mockPlatform, signInOption: SignInOption.games);
      verify(mockPlatform.signInSilently());
    });

    test('authentication', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();
      when(mockPlatform.getTokens(
              email: anyNamed('email'),
              shouldRecoverAuth: anyNamed('shouldRecoverAuth')))
          .thenAnswer((Invocation _) async => GoogleSignInTokenData(
                idToken: '123',
                accessToken: '456',
                serverAuthCode: '789',
              ));

      await googleSignIn.signIn();

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

      expect(auth.accessToken, '456');
      expect(auth.idToken, '123');
      verify(mockPlatform.getTokens(
          email: 'john.doe@gmail.com', shouldRecoverAuth: true));
    });

    test('requestScopes returns true once new scope is granted', () async {
      final GoogleSignIn googleSignIn = GoogleSignIn();
      when(mockPlatform.requestScopes(any))
          .thenAnswer((Invocation _) async => true);

      await googleSignIn.signIn();
      final bool result =
          await googleSignIn.requestScopes(<String>['testScope']);

      expect(result, isTrue);
      _verifyInit(mockPlatform);
      verify(mockPlatform.signIn());
      verify(mockPlatform.requestScopes(<String>['testScope']));
    });

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

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

      final GoogleSignInAccount user = googleSignIn.currentUser!;

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

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

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

void _verifyInit(
  MockGoogleSignInPlatform mockSignIn, {
  SignInOption signInOption = SignInOption.standard,
  String? clientId,
}) {
  verify(mockSignIn.init(
    signInOption: signInOption,
    scopes: <String>[],
    hostedDomain: null,
    clientId: clientId,
  ));
}
