// 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:http/http.dart' as http;
import 'package:oauth2/oauth2.dart' as oauth2;
import 'package:test/test.dart';

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', () {
      const codeVerifier =
          'it1shei7LooGoh3looxaa4sieveijeib2zecauz2oo8aebae5aehee0ahPirewoh'
          '5Bo6Maexooqui3uL2si6ahweiv7shauc1shahxooveoB3aeyahsaiye0Egh3raix';
      const 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(isA<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) => 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) => Future.value(
          http.Response(
            jsonEncode({
              'access_token': 'new access token',
              'token_type': 'bearer',
            }),
            200,
            headers: {'content-type': 'application/json'},
          ),
        ),
      );

      client.expectRequest(
          (request) => Future.value(http.Response('good job', 200)));

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

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