// 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: avoid_implementing_value_types, 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,
        ),
  )));
}
