// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. 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 'dart:convert';

import 'package:test/test.dart';
import 'package:http/http.dart' as http;
import 'package:oauth2/oauth2.dart' as oauth2;

import 'utils.dart';

final redirectUrl = Uri.parse('http://example.com/redirect');

void main() {
  late ExpectClient client;
  late oauth2.AuthorizationCodeGrant grant;
  setUp(() {
    client = ExpectClient();
    grant = oauth2.AuthorizationCodeGrant(
        'identifier',
        Uri.parse('https://example.com/authorization'),
        Uri.parse('https://example.com/token'),
        secret: 'secret',
        httpClient: client);
  });

  group('.getAuthorizationUrl', () {
    test('builds the correct URL', () {
      expect(
          grant.getAuthorizationUrl(redirectUrl).toString(),
          allOf([
            startsWith('https://example.com/authorization?response_type=code'),
            contains('&client_id=identifier'),
            contains('&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'),
            matches(r'&code_challenge=[A-Za-z0-9\+\/\-\_]{43}'),
            contains('&code_challenge_method=S256')
          ]));
    });

    test('builds the correct URL with scopes', () {
      var authorizationUrl = grant
          .getAuthorizationUrl(redirectUrl, scopes: ['scope', 'other/scope']);
      expect(
          authorizationUrl.toString(),
          allOf([
            startsWith('https://example.com/authorization?response_type=code'),
            contains('&client_id=identifier'),
            contains('&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'),
            matches(r'&code_challenge=[A-Za-z0-9\+\/\-\_]{43}'),
            contains('&code_challenge_method=S256'),
            contains('&scope=scope+other%2Fscope')
          ]));
    });

    test('builds the correct URL with passed in code verifier', () {
      final codeVerifier =
          'it1shei7LooGoh3looxaa4sieveijeib2zecauz2oo8aebae5aehee0ahPirewoh5Bo6Maexooqui3uL2si6ahweiv7shauc1shahxooveoB3aeyahsaiye0Egh3raix';
      final expectedCodeChallenge =
          'EjfFMv8TFPd3GuNxAn5COhlWBGpfZLimHett7ypJfJ0';
      var grant = oauth2.AuthorizationCodeGrant(
          'identifier',
          Uri.parse('https://example.com/authorization'),
          Uri.parse('https://example.com/token'),
          secret: 'secret',
          httpClient: client,
          codeVerifier: codeVerifier);
      expect(
          grant.getAuthorizationUrl(redirectUrl).toString(),
          allOf([
            startsWith('https://example.com/authorization?response_type=code'),
            contains('&client_id=identifier'),
            contains('&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'),
            contains('&code_challenge=$expectedCodeChallenge'),
            contains('&code_challenge_method=S256')
          ]));
    });

    test('separates scopes with the correct delimiter', () {
      var grant = oauth2.AuthorizationCodeGrant(
          'identifier',
          Uri.parse('https://example.com/authorization'),
          Uri.parse('https://example.com/token'),
          secret: 'secret',
          httpClient: client,
          delimiter: '_');
      var authorizationUrl = grant
          .getAuthorizationUrl(redirectUrl, scopes: ['scope', 'other/scope']);
      expect(
          authorizationUrl.toString(),
          allOf([
            startsWith('https://example.com/authorization?response_type=code'),
            contains('&client_id=identifier'),
            contains('&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'),
            matches(r'&code_challenge=[A-Za-z0-9\+\/\-\_]{43}'),
            contains('&code_challenge_method=S256'),
            contains('&scope=scope_other%2Fscope')
          ]));
    });

    test('builds the correct URL with state', () {
      var authorizationUrl =
          grant.getAuthorizationUrl(redirectUrl, state: 'state');
      expect(
          authorizationUrl.toString(),
          allOf([
            startsWith('https://example.com/authorization?response_type=code'),
            contains('&client_id=identifier'),
            contains('&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'),
            matches(r'&code_challenge=[A-Za-z0-9\+\/\-\_]{43}'),
            contains('&code_challenge_method=S256'),
            contains('&state=state')
          ]));
    });

    test('merges with existing query parameters', () {
      grant = oauth2.AuthorizationCodeGrant(
          'identifier',
          Uri.parse('https://example.com/authorization?query=value'),
          Uri.parse('https://example.com/token'),
          secret: 'secret',
          httpClient: client);

      var authorizationUrl = grant.getAuthorizationUrl(redirectUrl);
      expect(
          authorizationUrl.toString(),
          allOf([
            startsWith('https://example.com/authorization?query=value'),
            contains('&response_type=code'),
            contains('&client_id=identifier'),
            contains('&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'),
            matches(r'&code_challenge=[A-Za-z0-9\+\/\-\_]{43}'),
            contains('&code_challenge_method=S256'),
          ]));
    });

    test("can't be called twice", () {
      grant.getAuthorizationUrl(redirectUrl);
      expect(() => grant.getAuthorizationUrl(redirectUrl), throwsStateError);
    });
  });

  group('.handleAuthorizationResponse', () {
    test("can't be called before .getAuthorizationUrl", () {
      expect(grant.handleAuthorizationResponse({}), throwsStateError);
    });

    test("can't be called twice", () {
      grant.getAuthorizationUrl(redirectUrl);
      expect(grant.handleAuthorizationResponse({'code': 'auth code'}),
          throwsFormatException);
      expect(grant.handleAuthorizationResponse({'code': 'auth code'}),
          throwsStateError);
    });

    test('must have a state parameter if the authorization URL did', () {
      grant.getAuthorizationUrl(redirectUrl, state: 'state');
      expect(grant.handleAuthorizationResponse({'code': 'auth code'}),
          throwsFormatException);
    });

    test('must have the same state parameter the authorization URL did', () {
      grant.getAuthorizationUrl(redirectUrl, state: 'state');
      expect(
          grant.handleAuthorizationResponse(
              {'code': 'auth code', 'state': 'other state'}),
          throwsFormatException);
    });

    test('must have a code parameter', () {
      grant.getAuthorizationUrl(redirectUrl);
      expect(grant.handleAuthorizationResponse({}), throwsFormatException);
    });

    test('with an error parameter throws an AuthorizationException', () {
      grant.getAuthorizationUrl(redirectUrl);
      expect(grant.handleAuthorizationResponse({'error': 'invalid_request'}),
          throwsA((e) => e is oauth2.AuthorizationException));
    });

    test('sends an authorization code request', () {
      grant.getAuthorizationUrl(redirectUrl);
      client.expectRequest((request) {
        expect(request.method, equals('POST'));
        expect(request.url.toString(), equals(grant.tokenEndpoint.toString()));
        expect(
            request.bodyFields,
            allOf([
              containsPair('grant_type', 'authorization_code'),
              containsPair('code', 'auth code'),
              containsPair('redirect_uri', redirectUrl.toString()),
              containsPair(
                  'code_verifier', matches(r'[A-Za-z0-9\-\.\_\~]{128}'))
            ]));
        expect(request.headers,
            containsPair('Authorization', 'Basic aWRlbnRpZmllcjpzZWNyZXQ='));

        return Future.value(http.Response(
            jsonEncode({
              'access_token': 'access token',
              'token_type': 'bearer',
            }),
            200,
            headers: {'content-type': 'application/json'}));
      });

      expect(
          grant.handleAuthorizationResponse({'code': 'auth code'}).then(
              (client) => client.credentials.accessToken),
          completion(equals('access token')));
    });
  });

  group('.handleAuthorizationCode', () {
    test("can't be called before .getAuthorizationUrl", () {
      expect(grant.handleAuthorizationCode('auth code'), throwsStateError);
    });

    test("can't be called twice", () {
      grant.getAuthorizationUrl(redirectUrl);
      expect(grant.handleAuthorizationCode('auth code'), throwsFormatException);
      expect(grant.handleAuthorizationCode('auth code'), throwsStateError);
    });

    test('sends an authorization code request', () async {
      grant.getAuthorizationUrl(redirectUrl);
      client.expectRequest((request) {
        expect(request.method, equals('POST'));
        expect(request.url.toString(), equals(grant.tokenEndpoint.toString()));
        expect(
            request.bodyFields,
            allOf([
              containsPair('grant_type', 'authorization_code'),
              containsPair('code', 'auth code'),
              containsPair('redirect_uri', redirectUrl.toString()),
              containsPair(
                  'code_verifier', matches(r'[A-Za-z0-9\-\.\_\~]{128}'))
            ]));
        expect(request.headers,
            containsPair('Authorization', 'Basic aWRlbnRpZmllcjpzZWNyZXQ='));

        return Future.value(http.Response(
            jsonEncode({
              'access_token': 'access token',
              'token_type': 'bearer',
            }),
            200,
            headers: {'content-type': 'application/json'}));
      });

      expect(
          await grant.handleAuthorizationCode('auth code'),
          isA<oauth2.Client>().having((c) => c.credentials.accessToken,
              'credentials.accessToken', 'access token'));
    });
  });

  group('with basicAuth: false', () {
    setUp(() {
      client = ExpectClient();
      grant = oauth2.AuthorizationCodeGrant(
          'identifier',
          Uri.parse('https://example.com/authorization'),
          Uri.parse('https://example.com/token'),
          secret: 'secret',
          basicAuth: false,
          httpClient: client);
    });

    test('.handleAuthorizationResponse sends an authorization code request',
        () {
      grant.getAuthorizationUrl(redirectUrl);
      client.expectRequest((request) {
        expect(request.method, equals('POST'));
        expect(request.url.toString(), equals(grant.tokenEndpoint.toString()));
        expect(
            request.bodyFields,
            allOf([
              containsPair('grant_type', 'authorization_code'),
              containsPair('code', 'auth code'),
              containsPair('redirect_uri', redirectUrl.toString()),
              containsPair(
                  'code_verifier', matches(r'[A-Za-z0-9\-\.\_\~]{128}')),
              containsPair('client_id', 'identifier'),
              containsPair('client_secret', 'secret')
            ]));

        return Future.value(http.Response(
            jsonEncode({
              'access_token': 'access token',
              'token_type': 'bearer',
            }),
            200,
            headers: {'content-type': 'application/json'}));
      });

      expect(
          grant.handleAuthorizationResponse({'code': 'auth code'}).then(
              (client) => client.credentials.accessToken),
          completion(equals('access token')));
    });

    test('.handleAuthorizationCode sends an authorization code request',
        () async {
      grant.getAuthorizationUrl(redirectUrl);
      client.expectRequest((request) {
        expect(request.method, equals('POST'));
        expect(request.url.toString(), equals(grant.tokenEndpoint.toString()));
        expect(
            request.bodyFields,
            allOf([
              containsPair('grant_type', 'authorization_code'),
              containsPair('code', 'auth code'),
              containsPair('redirect_uri', redirectUrl.toString()),
              containsPair(
                  'code_verifier', matches(r'[A-Za-z0-9\-\.\_\~]{128}')),
              containsPair('client_id', 'identifier'),
              containsPair('client_secret', 'secret')
            ]));

        return Future.value(http.Response(
            jsonEncode({
              'access_token': 'access token',
              'token_type': 'bearer',
            }),
            200,
            headers: {'content-type': 'application/json'}));
      });

      expect(
          await grant.handleAuthorizationCode('auth code'),
          isA<oauth2.Client>().having((c) => c.credentials.accessToken,
              'credentials.accessToken', 'access token'));
    });
  });

  group('onCredentialsRefreshed', () {
    test('is correctly propagated', () async {
      var isCallbackInvoked = false;
      var grant = oauth2.AuthorizationCodeGrant(
          'identifier',
          Uri.parse('https://example.com/authorization'),
          Uri.parse('https://example.com/token'),
          secret: 'secret',
          basicAuth: false,
          httpClient: client, onCredentialsRefreshed: (credentials) {
        isCallbackInvoked = true;
      });

      grant.getAuthorizationUrl(redirectUrl);
      client.expectRequest((request) {
        return Future.value(http.Response(
            jsonEncode({
              'access_token': 'access token',
              'token_type': 'bearer',
              'expires_in': -3600,
              'refresh_token': 'refresh token',
            }),
            200,
            headers: {'content-type': 'application/json'}));
      });

      var oauth2Client = await grant.handleAuthorizationCode('auth code');

      client.expectRequest((request) {
        return Future.value(http.Response(
            jsonEncode(
                {'access_token': 'new access token', 'token_type': 'bearer'}),
            200,
            headers: {'content-type': 'application/json'}));
      });

      client.expectRequest((request) {
        return Future.value(http.Response('good job', 200));
      });

      await oauth2Client.read(Uri.parse('http://example.com/resource'));

      expect(isCallbackInvoked, equals(true));
    });
  });
}
