// 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 Uri tokenEndpoint = Uri.parse('http://example.com/token');

void main() {
  var httpClient;
  setUp(() => httpClient = ExpectClient());

  test('is not expired if no expiration exists', () {
    var credentials = oauth2.Credentials('access token');
    expect(credentials.isExpired, isFalse);
  });

  test('is not expired if the expiration is in the future', () {
    var expiration = DateTime.now().add(Duration(hours: 1));
    var credentials =
        oauth2.Credentials('access token', expiration: expiration);
    expect(credentials.isExpired, isFalse);
  });

  test('is expired if the expiration is in the past', () {
    var expiration = DateTime.now().subtract(Duration(hours: 1));
    var credentials =
        oauth2.Credentials('access token', expiration: expiration);
    expect(credentials.isExpired, isTrue);
  });

  test("can't refresh without a refresh token", () {
    var credentials =
        oauth2.Credentials('access token', tokenEndpoint: tokenEndpoint);
    expect(credentials.canRefresh, false);

    expect(
        credentials.refresh(
            identifier: 'identifier', secret: 'secret', httpClient: httpClient),
        throwsStateError);
  });

  test("can't refresh without a token endpoint", () {
    var credentials =
        oauth2.Credentials('access token', refreshToken: 'refresh token');
    expect(credentials.canRefresh, false);

    expect(
        credentials.refresh(
            identifier: 'identifier', secret: 'secret', httpClient: httpClient),
        throwsStateError);
  });

  test('can refresh with a refresh token and a token endpoint', () async {
    var credentials = oauth2.Credentials('access token',
        refreshToken: 'refresh token',
        tokenEndpoint: tokenEndpoint,
        scopes: ['scope1', 'scope2']);
    expect(credentials.canRefresh, true);

    httpClient.expectRequest((request) {
      expect(request.method, equals('POST'));
      expect(request.url.toString(), equals(tokenEndpoint.toString()));
      expect(
          request.bodyFields,
          equals({
            'grant_type': 'refresh_token',
            'refresh_token': 'refresh token',
            'scope': 'scope1 scope2'
          }));
      expect(
          request.headers,
          containsPair('Authorization',
              'Basic aWQlQzMlQUJudCVDNCVBQmZpZXI6cyVDMyVBQmNyZXQ='));

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

    credentials = await credentials.refresh(
        identifier: 'idëntīfier', secret: 'sëcret', httpClient: httpClient);
    expect(credentials.accessToken, equals('new access token'));
    expect(credentials.refreshToken, equals('new refresh token'));
  });

  test('sets proper scope string when using custom delimiter', () async {
    var credentials = oauth2.Credentials('access token',
        refreshToken: 'refresh token',
        tokenEndpoint: tokenEndpoint,
        scopes: ['scope1', 'scope2'],
        delimiter: ',');
    httpClient.expectRequest((http.Request request) {
      expect(request.bodyFields['scope'], equals('scope1,scope2'));
      return Future.value(http.Response(
          jsonEncode({
            'access_token': 'new access token',
            'token_type': 'bearer',
            'refresh_token': 'new refresh token'
          }),
          200,
          headers: {'content-type': 'application/json'}));
    });
    await credentials.refresh(
        identifier: 'idëntīfier', secret: 'sëcret', httpClient: httpClient);
  });

  test('can refresh without a client secret', () async {
    var credentials = oauth2.Credentials('access token',
        refreshToken: 'refresh token',
        tokenEndpoint: tokenEndpoint,
        scopes: ['scope1', 'scope2']);
    expect(credentials.canRefresh, true);

    httpClient.expectRequest((request) {
      expect(request.method, equals('POST'));
      expect(request.url.toString(), equals(tokenEndpoint.toString()));
      expect(
          request.bodyFields,
          equals({
            'grant_type': 'refresh_token',
            'refresh_token': 'refresh token',
            'scope': 'scope1 scope2',
            'client_id': 'identifier'
          }));

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

    credentials = await credentials.refresh(
        identifier: 'identifier', httpClient: httpClient);
    expect(credentials.accessToken, equals('new access token'));
    expect(credentials.refreshToken, equals('new refresh token'));
  });

  test('can refresh without client authentication', () async {
    var credentials = oauth2.Credentials('access token',
        refreshToken: 'refresh token',
        tokenEndpoint: tokenEndpoint,
        scopes: ['scope1', 'scope2']);
    expect(credentials.canRefresh, true);

    httpClient.expectRequest((request) {
      expect(request.method, equals('POST'));
      expect(request.url.toString(), equals(tokenEndpoint.toString()));
      expect(
          request.bodyFields,
          equals({
            'grant_type': 'refresh_token',
            'refresh_token': 'refresh token',
            'scope': 'scope1 scope2'
          }));

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

    credentials = await credentials.refresh(httpClient: httpClient);
    expect(credentials.accessToken, equals('new access token'));
    expect(credentials.refreshToken, equals('new refresh token'));
  });

  test("uses the old refresh token if a new one isn't provided", () async {
    var credentials = oauth2.Credentials('access token',
        refreshToken: 'refresh token', tokenEndpoint: tokenEndpoint);
    expect(credentials.canRefresh, true);

    httpClient.expectRequest((request) {
      expect(request.method, equals('POST'));
      expect(request.url.toString(), equals(tokenEndpoint.toString()));
      expect(
          request.bodyFields,
          equals({
            'grant_type': 'refresh_token',
            'refresh_token': 'refresh token'
          }));
      expect(
          request.headers,
          containsPair('Authorization',
              'Basic aWQlQzMlQUJudCVDNCVBQmZpZXI6cyVDMyVBQmNyZXQ='));

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

    credentials = await credentials.refresh(
        identifier: 'idëntīfier', secret: 'sëcret', httpClient: httpClient);
    expect(credentials.accessToken, equals('new access token'));
    expect(credentials.refreshToken, equals('refresh token'));
  });

  test('uses form-field authentication if basicAuth is false', () async {
    var credentials = oauth2.Credentials('access token',
        refreshToken: 'refresh token',
        tokenEndpoint: tokenEndpoint,
        scopes: ['scope1', 'scope2']);
    expect(credentials.canRefresh, true);

    httpClient.expectRequest((request) {
      expect(request.method, equals('POST'));
      expect(request.url.toString(), equals(tokenEndpoint.toString()));
      expect(
          request.bodyFields,
          equals({
            'grant_type': 'refresh_token',
            'refresh_token': 'refresh token',
            'scope': 'scope1 scope2',
            'client_id': 'idëntīfier',
            'client_secret': 'sëcret'
          }));

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

    credentials = await credentials.refresh(
        identifier: 'idëntīfier',
        secret: 'sëcret',
        basicAuth: false,
        httpClient: httpClient);
    expect(credentials.accessToken, equals('new access token'));
    expect(credentials.refreshToken, equals('new refresh token'));
  });

  group('fromJson', () {
    oauth2.Credentials fromMap(Map map) =>
        oauth2.Credentials.fromJson(jsonEncode(map));

    test('should load the same credentials from toJson', () {
      // Round the expiration down to milliseconds since epoch, since that's
      // what the credentials file stores. Otherwise sub-millisecond time gets
      // in the way.
      var expiration = DateTime.now().subtract(Duration(hours: 1));
      expiration = DateTime.fromMillisecondsSinceEpoch(
          expiration.millisecondsSinceEpoch);

      var credentials = oauth2.Credentials('access token',
          refreshToken: 'refresh token',
          idToken: 'id token',
          tokenEndpoint: tokenEndpoint,
          scopes: ['scope1', 'scope2'],
          expiration: expiration);
      var reloaded = oauth2.Credentials.fromJson(credentials.toJson());

      expect(reloaded.accessToken, equals(credentials.accessToken));
      expect(reloaded.refreshToken, equals(credentials.refreshToken));
      expect(reloaded.idToken, equals(credentials.idToken));
      expect(reloaded.tokenEndpoint.toString(),
          equals(credentials.tokenEndpoint.toString()));
      expect(reloaded.scopes, equals(credentials.scopes));
      expect(reloaded.expiration, equals(credentials.expiration));
    });

    test('should throw a FormatException for invalid JSON', () {
      expect(
          () => oauth2.Credentials.fromJson('foo bar'), throwsFormatException);
    });

    test("should throw a FormatException for JSON that's not a map", () {
      expect(() => oauth2.Credentials.fromJson('null'), throwsFormatException);
    });

    test('should throw a FormatException if there is no accessToken', () {
      expect(() => fromMap({}), throwsFormatException);
    });

    test('should throw a FormatException if accessToken is not a string', () {
      expect(() => fromMap({'accessToken': 12}), throwsFormatException);
    });

    test('should throw a FormatException if refreshToken is not a string', () {
      expect(() => fromMap({'accessToken': 'foo', 'refreshToken': 12}),
          throwsFormatException);
    });

    test('should throw a FormatException if idToken is not a string', () {
      expect(() => fromMap({'accessToken': 'foo', 'idToken': 12}),
          throwsFormatException);
    });

    test('should throw a FormatException if tokenEndpoint is not a string', () {
      expect(() => fromMap({'accessToken': 'foo', 'tokenEndpoint': 12}),
          throwsFormatException);
    });

    test('should throw a FormatException if scopes is not a list', () {
      expect(() => fromMap({'accessToken': 'foo', 'scopes': 12}),
          throwsFormatException);
    });

    test('should throw a FormatException if expiration is not an int', () {
      expect(() => fromMap({'accessToken': 'foo', 'expiration': '12'}),
          throwsFormatException);
    });
  });
}
