// 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';

/// Verify that [GoogleSignInAccount] can be mocked even though it's unused
// ignore: must_be_immutable
class MockGoogleSignInAccount extends Mock implements GoogleSignInAccount {}

@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('clientId parameter is forwarded to implementation', () async {
      const String fakeClientId = 'fakeClientId';
      final GoogleSignIn googleSignIn = GoogleSignIn(clientId: fakeClientId);

      await googleSignIn.signIn();

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

    test('serverClientId parameter is forwarded to implementation', () async {
      const String fakeServerClientId = 'fakeServerClientId';
      final GoogleSignIn googleSignIn =
          GoogleSignIn(serverClientId: fakeServerClientId);

      await googleSignIn.signIn();

      _verifyInit(mockPlatform, serverClientId: fakeServerClientId);
      verify(mockPlatform.signIn());
    });

    test('forceCodeForRefreshToken sent with init method call', () async {
      final GoogleSignIn googleSignIn =
          GoogleSignIn(forceCodeForRefreshToken: true);

      await googleSignIn.signIn();

      _verifyInit(mockPlatform, forceCodeForRefreshToken: true);
      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.initWithParams(any))
          .thenThrow(Exception('First init fails'));
      expect(googleSignIn.signIn(), throwsA(isInstanceOf<Exception>()));

      when(mockPlatform.initWithParams(any))
          .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, {
  List<String> scopes = const <String>[],
  SignInOption signInOption = SignInOption.standard,
  String? hostedDomain,
  String? clientId,
  String? serverClientId,
  bool forceCodeForRefreshToken = false,
}) {
  verify(mockSignIn.initWithParams(argThat(
    isA<SignInInitParameters>()
        .having(
          (SignInInitParameters p) => p.scopes,
          'scopes',
          scopes,
        )
        .having(
          (SignInInitParameters p) => p.signInOption,
          'signInOption',
          signInOption,
        )
        .having(
          (SignInInitParameters p) => p.hostedDomain,
          'hostedDomain',
          hostedDomain,
        )
        .having(
          (SignInInitParameters p) => p.clientId,
          'clientId',
          clientId,
        )
        .having(
          (SignInInitParameters p) => p.serverClientId,
          'serverClientId',
          serverClientId,
        )
        .having(
          (SignInInitParameters p) => p.forceCodeForRefreshToken,
          'forceCodeForRefreshToken',
          forceCodeForRefreshToken,
        ),
  )));
}
