// 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 '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_platform_interface/src/types.dart';
import 'package:google_sign_in_platform_interface/src/utils.dart';

const Map<String, String> kUserData = <String, String>{
  "email": "john.doe@gmail.com",
  "id": "8162538176523816253123",
  "photoUrl": "https://lh5.googleusercontent.com/photo.jpg",
  "displayName": "John Doe",
  'idToken': '123',
  'serverAuthCode': '789',
};

const Map<dynamic, dynamic> kTokenData = <String, dynamic>{
  'idToken': '123',
  'accessToken': '456',
  'serverAuthCode': '789',
};

const Map<String, dynamic> kDefaultResponses = <String, dynamic>{
  'init': null,
  'signInSilently': kUserData,
  'signIn': kUserData,
  'signOut': null,
  'disconnect': null,
  'isSignedIn': true,
  'getTokens': kTokenData,
  'requestScopes': true,
};

final GoogleSignInUserData? kUser = getUserDataFromMap(kUserData);
final GoogleSignInTokenData? kToken =
    getTokenDataFromMap(kTokenData as Map<String, dynamic>);

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  group('$MethodChannelGoogleSignIn', () {
    final MethodChannelGoogleSignIn googleSignIn = MethodChannelGoogleSignIn();
    final MethodChannel channel = googleSignIn.channel;

    final List<MethodCall> log = <MethodCall>[];
    late Map<String, dynamic>
        responses; // Some tests mutate some kDefaultResponses

    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);
      });
      log.clear();
    });

    test('signInSilently transforms platform data to GoogleSignInUserData',
        () async {
      final dynamic response = await googleSignIn.signInSilently();
      expect(response, kUser);
    });
    test('signInSilently Exceptions -> throws', () async {
      responses['signInSilently'] = Exception('Not a user');
      expect(googleSignIn.signInSilently(),
          throwsA(isInstanceOf<PlatformException>()));
    });

    test('signIn transforms platform data to GoogleSignInUserData', () async {
      final dynamic response = await googleSignIn.signIn();
      expect(response, kUser);
    });
    test('signIn Exceptions -> throws', () async {
      responses['signIn'] = Exception('Not a user');
      expect(googleSignIn.signIn(), throwsA(isInstanceOf<PlatformException>()));
    });

    test('getTokens transforms platform data to GoogleSignInTokenData',
        () async {
      final dynamic response = await googleSignIn.getTokens(
          email: 'example@example.com', shouldRecoverAuth: false);
      expect(response, kToken);
      expect(
          log[0],
          isMethodCall('getTokens', arguments: <String, dynamic>{
            'email': 'example@example.com',
            'shouldRecoverAuth': false,
          }));
    });

    test('Other functions pass through arguments to the channel', () async {
      final Map<Function, Matcher> tests = <Function, Matcher>{
        () {
          googleSignIn.init(
              hostedDomain: 'example.com',
              scopes: <String>['two', 'scopes'],
              signInOption: SignInOption.games,
              clientId: 'fakeClientId');
        }: isMethodCall('init', arguments: <String, dynamic>{
          'hostedDomain': 'example.com',
          'scopes': <String>['two', 'scopes'],
          'signInOption': 'SignInOption.games',
          'clientId': 'fakeClientId',
        }),
        () {
          googleSignIn.getTokens(
              email: 'example@example.com', shouldRecoverAuth: false);
        }: isMethodCall('getTokens', arguments: <String, dynamic>{
          'email': 'example@example.com',
          'shouldRecoverAuth': false,
        }),
        () {
          googleSignIn.clearAuthCache(token: 'abc');
        }: isMethodCall('clearAuthCache', arguments: <String, dynamic>{
          'token': 'abc',
        }),
        () {
          googleSignIn.requestScopes(['newScope', 'anotherScope']);
        }: isMethodCall('requestScopes', arguments: <String, dynamic>{
          'scopes': ['newScope', 'anotherScope'],
        }),
        googleSignIn.signOut: isMethodCall('signOut', arguments: null),
        googleSignIn.disconnect: isMethodCall('disconnect', arguments: null),
        googleSignIn.isSignedIn: isMethodCall('isSignedIn', arguments: null),
      };

      tests.keys.forEach((Function f) => f());

      expect(log, tests.values);
    });
  });
}
