// 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 'dart:io';
import 'dart:math';

import 'package:collection/collection.dart';
import 'package:crypto/crypto.dart';
import 'package:http/http.dart' as http;
import 'package:http/retry.dart';
import 'package:http_parser/http_parser.dart';
import 'package:path/path.dart' as path;
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf_io;

import 'http.dart';
import 'io.dart';
import 'log.dart' as log;
import 'utils.dart';

/// The global HTTP client with basic retries. Used instead of retryForHttp for
/// OAuth calls because the OAuth2 package requires a client to be passed. While
/// the retry logic is more basic, this is fine for the publishing process.
final _retryHttpClient = RetryClient(
  globalHttpClient,
  when: (response) => response.statusCode >= 500,
  whenError: (e, _) => isHttpIOException(e),
);

/// The pub client's OAuth2 identifier.
const _identifier =
    '818368855108-8grd2eg9tj9f38os6f1urbcvsq399u8n.apps.googleusercontent.com';

/// The pub client's OAuth2 secret.
///
/// This isn't actually meant to be kept a secret.
const _secret = 'SWeqj8seoJW0w7_CpEPFLX0K';

/// The URL from which the pub client will retrieve Google's OIDC endpoint URIs.
///
/// [Google OpenID Connect documentation]: https://developers.google.com/identity/openid-connect/openid-connect#discovery
final _oidcDiscoveryDocumentEndpoint =
    Uri.https('accounts.google.com', '/.well-known/openid-configuration');

/// The URL to which the user will be directed to authorize the pub client to
/// get an OAuth2 access token.
///
/// `access_type=offline` and `approval_prompt=force` ensures that we always get
/// a refresh token from the server. See the [Google OAuth2 documentation][].
///
/// [Google OAuth2 documentation]: https://developers.google.com/accounts/docs/OAuth2WebServer#offline
final _authorizationEndpoint =
    Uri.parse('https://accounts.google.com/o/oauth2/auth?access_type=offline'
        '&approval_prompt=force');

/// The URL from which the pub client will request an access token once it's
/// been authorized by the user.
///
/// This can be controlled externally by setting the `_PUB_TEST_TOKEN_ENDPOINT`
/// environment variable.
Uri get tokenEndpoint {
  var tokenEndpoint = Platform.environment['_PUB_TEST_TOKEN_ENDPOINT'];
  if (tokenEndpoint != null) {
    return Uri.parse(tokenEndpoint);
  } else {
    return _tokenEndpoint;
  }
}

final _tokenEndpoint = Uri.parse('https://accounts.google.com/o/oauth2/token');

/// The OAuth2 scopes that the pub client needs.
///
/// Currently the client only needs the user's email so that the server can
/// verify their identity.
final _scopes = ['openid', 'https://www.googleapis.com/auth/userinfo.email'];

/// An in-memory cache of the user's OAuth2 credentials.
///
/// This should always be the same as the credentials file stored in the system
/// cache.
Credentials? _credentials;

/// Delete the cached credentials, if they exist.
void _clearCredentials() {
  _credentials = null;
  var credentialsFile = _credentialsFile();
  if (credentialsFile != null && entryExists(credentialsFile)) {
    deleteEntry(credentialsFile);
  }
}

/// Try to delete the cached credentials.
void logout() {
  var credentialsFile = _credentialsFile();
  if (credentialsFile != null && entryExists(credentialsFile)) {
    log.message('Logging out of pub.dev.');
    log.message('Deleting $credentialsFile');
    _clearCredentials();
  } else {
    log.message(
      'No existing credentials file $credentialsFile. Cannot log out.',
    );
  }
}

/// Asynchronously passes an OAuth2 [_Client] to [fn].
///
/// Does not close the client, since that would close the shared client. It must
/// be closed elsewhere.
///
/// This takes care of loading and saving the client's credentials, as well as
/// prompting the user for their authorization. It will also re-authorize and
/// re-run [fn] if a recoverable authorization error is detected.
Future<T> withClient<T>(Future<T> Function(http.Client) fn) {
  return _getClient().then((client) {
    return fn(client).whenComplete(() {
      // TODO(sigurdm): refactor the http subsystem, so we can close [client]
      // here.

      // Be sure to save the credentials even when an error happens.
      _saveCredentials(client.credentials);
    });
  }).catchError((error) {
    if (error is _ExpirationException) {
      log.error("Pub's authorization to upload packages has expired and "
          "can't be automatically refreshed.");
      return withClient(fn);
    } else if (error is _AuthorizationException) {
      var message = 'OAuth2 authorization failed';
      if (error.description != null) {
        message = '$message (${error.description})';
      }
      log.error('$message.');
      _clearCredentials();
      return withClient(fn);
    } else {
      // ignore: only_throw_errors
      throw error as Object;
    }
  });
}

/// Gets a new OAuth2 client.
///
/// If saved credentials are available, those are used; otherwise, the user is
/// prompted to authorize the pub client.
Future<_Client> _getClient() async {
  var credentials = loadCredentials();
  if (credentials == null) return await _authorize();

  var client = _Client(
    credentials,
    identifier: _identifier,
    secret: _secret,
    // Google's OAuth2 API doesn't support basic auth.
    basicAuth: false,
    httpClient: _retryHttpClient,
  );
  _saveCredentials(client.credentials);
  return client;
}

/// Loads the user's OAuth2 credentials from the in-memory cache or the
/// filesystem if possible.
///
/// If the credentials can't be loaded for any reason, the returned [Future]
/// completes to `null`.
Credentials? loadCredentials() {
  log.fine('Loading OAuth2 credentials.');

  try {
    if (_credentials != null) return _credentials;

    var path = _credentialsFile();
    if (path == null || !fileExists(path)) return null;

    var credentials = Credentials.fromJson(readTextFile(path));
    if (credentials.isExpired && !credentials.canRefresh) {
      log.error("Pub's authorization to upload packages has expired and "
          "can't be automatically refreshed.");
      return null; // null means re-authorize.
    }

    return credentials;
  } catch (e) {
    // Don't print the error message itself here. I might be leaking data about
    // credentials.
    log.error('Warning: could not load the saved OAuth2 credentials.\n'
        'Obtaining new credentials...');
    return null; // null means re-authorize.
  }
}

/// Save the user's OAuth2 credentials to the in-memory cache and the
/// filesystem.
void _saveCredentials(Credentials credentials) {
  log.fine('Saving OAuth2 credentials.');
  _credentials = credentials;
  var credentialsPath = _credentialsFile();
  if (credentialsPath != null) {
    ensureDir(path.dirname(credentialsPath));
    writeTextFile(credentialsPath, credentials.toJson(), dontLogContents: true);
  }
}

/// The path to the file in which the user's OAuth2 credentials are stored.
///
/// Returns `null` if there is no good place for the file.
String? _credentialsFile() {
  final configDir = dartConfigDir;
  return configDir == null
      ? null
      : path.join(configDir, 'pub-credentials.json');
}

/// Gets the user to authorize pub as a client of pub.dev via oauth2.
///
/// Returns a Future that completes to a fully-authorized [_Client].
Future<_Client> _authorize() async {
  var grant = _AuthorizationCodeGrant(
    _identifier, _authorizationEndpoint, tokenEndpoint,
    secret: _secret,
    // Google's OAuth2 API doesn't support basic auth.
    basicAuth: false,
    httpClient: _retryHttpClient,
  );

  // Spin up a one-shot HTTP server to receive the authorization code from the
  // Google OAuth2 server via redirect. This server will close itself as soon as
  // the code is received.
  var completer = Completer<_Client>();
  var server = await bindServer('localhost', 0);
  shelf_io.serveRequests(server, (request) {
    if (request.url.path.isNotEmpty) {
      return shelf.Response.notFound('Invalid URI.');
    }

    log.message('Authorization received, processing...');
    var queryString = request.url.query;
    // Closing the server here is safe, since it will wait until the response
    // is sent to actually shut down.
    server.close();
    completer
        .complete(grant.handleAuthorizationResponse(queryToMap(queryString)));

    return shelf.Response.found('https://pub.dev/authorized');
  });

  var authUrl = grant.getAuthorizationUrl(
    Uri.parse('http://localhost:${server.port}'),
    scopes: _scopes,
  );

  log.message(
      'Pub needs your authorization to upload packages on your behalf.\n'
      'In a web browser, go to $authUrl\n'
      'Then click "Allow access".\n\n'
      'Waiting for your authorization...');

  var client = await completer.future;
  log.message('Successfully authorized.\n');
  return client;
}

/// Fetches Google's OpenID Connect Discovery document and parses the JSON
/// response body into a [Map].
///
/// See https://developers.google.com/identity/openid-connect/openid-connect#discovery
Future<Map> fetchOidcDiscoveryDocument() async {
  final discoveryResponse = await retryForHttp(
      'fetching Google\'s OpenID Connect Discovery document', () async {
    final request = http.Request('GET', _oidcDiscoveryDocumentEndpoint);
    return await globalHttpClient.fetch(request);
  });
  return parseJsonResponse(discoveryResponse);
}

// The following code originates in package:oauth2.
// TODO(sigurdm): simplify to only do what we need.

/// A class for obtaining credentials via an [authorization code grant][].
///
/// This method of authorization involves sending the resource owner to the
/// authorization server where they will authorize the client. They're then
/// redirected back to your server, along with an authorization code. This is
/// used to obtain [Credentials] and create a fully-authorized [_Client].
///
/// To use this class, you must first call [getAuthorizationUrl] to get the URL
/// to which to redirect the resource owner. Then once they've been redirected
/// back to your application, call [handleAuthorizationResponse] or
/// [handleAuthorizationCode] to process the authorization server's response and
/// construct a [_Client].
///
/// [authorization code grant]: http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-4.1
class _AuthorizationCodeGrant {
  /// The function used to parse parameters from a host's response.
  final _GetParameters _getParameters;

  /// The client identifier for this client.
  ///
  /// The authorization server will issue each client a separate client
  /// identifier and secret, which allows the server to tell which client is
  /// accessing it. Some servers may also have an anonymous identifier/secret
  /// pair that any client may use.
  ///
  /// This is usually global to the program using this library.
  final String identifier;

  /// The client secret for this client.
  ///
  /// The authorization server will issue each client a separate client
  /// identifier and secret, which allows the server to tell which client is
  /// accessing it. Some servers may also have an anonymous identifier/secret
  /// pair that any client may use.
  ///
  /// This is usually global to the program using this library.
  ///
  /// Note that clients whose source code or binary executable is readily
  /// available may not be able to make sure the client secret is kept a secret.
  /// This is fine; OAuth2 servers generally won't rely on knowing with
  /// certainty that a client is who it claims to be.
  final String? secret;

  /// A URL provided by the authorization server that serves as the base for the
  /// URL that the resource owner will be redirected to to authorize this
  /// client.
  ///
  /// This will usually be listed in the authorization server's OAuth2 API
  /// documentation.
  final Uri authorizationEndpoint;

  /// A URL provided by the authorization server that this library uses to
  /// obtain long-lasting credentials.
  ///
  /// This will usually be listed in the authorization server's OAuth2 API
  /// documentation.
  final Uri tokenEndpoint;

  /// Callback to be invoked whenever the credentials are refreshed.
  ///
  /// This will be passed as-is to the constructed [_Client].
  final _CredentialsRefreshedCallback? _onCredentialsRefreshed;

  /// Whether to use HTTP Basic authentication for authorizing the client.
  final bool _basicAuth;

  /// A [String] used to separate scopes; defaults to `" "`.
  final String _delimiter;

  /// The HTTP client used to make HTTP requests.
  http.Client? _httpClient;

  /// The URL to which the resource owner will be redirected after they
  /// authorize this client with the authorization server.
  Uri? _redirectEndpoint;

  /// The scopes that the client is requesting access to.
  List<String>? _scopes;

  /// An opaque string that users of this library may specify that will be
  /// included in the response query parameters.
  String? _stateString;

  /// The current state of the grant object.
  _State _state = _State.initial;

  /// Allowed characters for generating the _codeVerifier
  static const String _charset =
      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';

  /// The PKCE code verifier. Will be generated if one is not provided in the
  /// constructor.
  final String _codeVerifier;

  /// Creates a new grant.
  ///
  /// If [basicAuth] is `true` (the default), the client credentials are sent to
  /// the server using using HTTP Basic authentication as defined in [RFC 2617].
  /// Otherwise, they're included in the request body. Note that the latter form
  /// is not recommended by the OAuth 2.0 spec, and should only be used if the
  /// server doesn't support Basic authentication.
  ///
  /// [RFC 2617]: https://tools.ietf.org/html/rfc2617
  ///
  /// [httpClient] is used for all HTTP requests made by this grant, as well as
  /// those of the [_Client] is constructs.
  ///
  /// [onCredentialsRefreshed] will be called by the constructed [_Client]
  /// whenever the credentials are refreshed.
  ///
  /// [codeVerifier] String to be used as PKCE code verifier. If none is
  /// provided a random codeVerifier will be generated.
  /// The codeVerifier must meet requirements specified in [RFC 7636].
  ///
  /// [RFC 7636]: https://tools.ietf.org/html/rfc7636#section-4.1
  ///
  /// The scope strings will be separated by the provided [delimiter]. This
  /// defaults to `" "`, the OAuth2 standard, but some APIs (such as Facebook's)
  /// use non-standard delimiters.
  ///
  /// By default, this follows the OAuth2 spec and requires the server's
  /// responses to be in JSON format. However, some servers return non-standard
  /// response formats, which can be parsed using the [getParameters] function.
  ///
  /// This function is passed the `Content-Type` header of the response as well
  /// as its body as a UTF-8-decoded string. It should return a map in the same
  /// format as the [standard JSON response][].
  ///
  /// [standard JSON response]: https://tools.ietf.org/html/rfc6749#section-5.1
  _AuthorizationCodeGrant(
    this.identifier,
    this.authorizationEndpoint,
    this.tokenEndpoint, {
    this.secret,
    String? delimiter,
    bool basicAuth = true,
    http.Client? httpClient,
    _CredentialsRefreshedCallback? onCredentialsRefreshed,
    Map<String, dynamic> Function(MediaType? contentType, String body)?
        getParameters,
    String? codeVerifier,
  })  : _basicAuth = basicAuth,
        _httpClient = httpClient ?? http.Client(),
        _delimiter = delimiter ?? ' ',
        _getParameters = getParameters ?? parseJsonParameters,
        _onCredentialsRefreshed = onCredentialsRefreshed,
        _codeVerifier = codeVerifier ?? _createCodeVerifier();

  /// Returns the URL to which the resource owner should be redirected to
  /// authorize this client.
  ///
  /// The resource owner will then be redirected to [redirect], which should
  /// point to a server controlled by the client. This redirect will have
  /// additional query parameters that should be passed to
  /// [handleAuthorizationResponse].
  ///
  /// The specific permissions being requested from the authorization server may
  /// be specified via [scopes]. The scope strings are specific to the
  /// authorization server and may be found in its documentation. Note that you
  /// may not be granted access to every scope you request; you may check the
  /// [Credentials.scopes] field of [_Client.credentials] to see which scopes you
  /// were granted.
  ///
  /// An opaque [state] string may also be passed that will be present in the
  /// query parameters provided to the redirect URL.
  ///
  /// It is a [StateError] to call this more than once.
  Uri getAuthorizationUrl(
    Uri redirect, {
    Iterable<String>? scopes,
    String? state,
  }) {
    if (_state != _State.initial) {
      throw StateError('The authorization URL has already been generated.');
    }
    _state = _State.awaitingResponse;

    var scopeList = scopes?.toList() ?? <String>[];
    var codeChallenge = base64Url
        .encode(sha256.convert(ascii.encode(_codeVerifier)).bytes)
        .replaceAll('=', '');

    _redirectEndpoint = redirect;
    _scopes = scopeList;
    _stateString = state;
    var parameters = {
      'response_type': 'code',
      'client_id': identifier,
      'redirect_uri': redirect.toString(),
      'code_challenge': codeChallenge,
      'code_challenge_method': 'S256',
    };

    if (state != null) parameters['state'] = state;
    if (scopeList.isNotEmpty) parameters['scope'] = scopeList.join(_delimiter);

    return _addQueryParameters(authorizationEndpoint, parameters);
  }

  /// Processes the query parameters added to a redirect from the authorization
  /// server.
  ///
  /// Note that this "response" is not an HTTP response, but rather the data
  /// passed to a server controlled by the client as query parameters on the
  /// redirect URL.
  ///
  /// It is a [StateError] to call this more than once, to call it before
  /// [getAuthorizationUrl] is called, or to call it after
  /// [handleAuthorizationCode] is called.
  ///
  /// Throws [FormatException] if [parameters] is invalid according to the
  /// OAuth2 spec or if the authorization server otherwise provides invalid
  /// responses. If `state` was passed to [getAuthorizationUrl], this will throw
  /// a [FormatException] if the `state` parameter doesn't match the original
  /// value.
  ///
  /// Throws [_AuthorizationException] if the authorization fails.
  Future<_Client> handleAuthorizationResponse(
    Map<String, String> parameters,
  ) async {
    if (_state == _State.initial) {
      throw StateError('The authorization URL has not yet been generated.');
    } else if (_state == _State.finished) {
      throw StateError('The authorization code has already been received.');
    }
    _state = _State.finished;

    if (_stateString != null) {
      if (!parameters.containsKey('state')) {
        throw FormatException('Invalid OAuth response for '
            '"$authorizationEndpoint": parameter "state" expected to be '
            '"$_stateString", was missing.');
      } else if (parameters['state'] != _stateString) {
        throw FormatException('Invalid OAuth response for '
            '"$authorizationEndpoint": parameter "state" expected to be '
            '"$_stateString", was "${parameters['state']}".');
      }
    }

    if (parameters.containsKey('error')) {
      var description = parameters['error_description'];
      var uriString = parameters['error_uri'];
      var uri = uriString == null ? null : Uri.parse(uriString);
      throw _AuthorizationException(parameters['error']!, description, uri);
    } else if (!parameters.containsKey('code')) {
      throw FormatException('Invalid OAuth response for '
          '"$authorizationEndpoint": did not contain required parameter '
          '"code".');
    }

    return _handleAuthorizationCode(parameters['code']);
  }

  /// Processes an authorization code directly.
  ///
  /// Usually [handleAuthorizationResponse] is preferable to this method, since
  /// it validates all of the query parameters. However, some authorization
  /// servers allow the user to copy and paste an authorization code into a
  /// command-line application, in which case this method must be used.
  ///
  /// It is a [StateError] to call this more than once, to call it before
  /// [getAuthorizationUrl] is called, or to call it after
  /// [handleAuthorizationCode] is called.
  ///
  /// Throws [FormatException] if the authorization server provides invalid
  /// responses while retrieving credentials.
  ///
  /// Throws [_AuthorizationException] if the authorization fails.
  Future<_Client> handleAuthorizationCode(String authorizationCode) async {
    if (_state == _State.initial) {
      throw StateError('The authorization URL has not yet been generated.');
    } else if (_state == _State.finished) {
      throw StateError('The authorization code has already been received.');
    }
    _state = _State.finished;

    return _handleAuthorizationCode(authorizationCode);
  }

  /// This works just like [handleAuthorizationCode], except it doesn't validate
  /// the state beforehand.
  Future<_Client> _handleAuthorizationCode(String? authorizationCode) async {
    var startTime = DateTime.now();

    var headers = <String, String>{};

    var body = {
      'grant_type': 'authorization_code',
      'code': authorizationCode,
      'redirect_uri': _redirectEndpoint.toString(),
      'code_verifier': _codeVerifier,
    };

    var secret = this.secret;
    if (_basicAuth && secret != null) {
      headers['Authorization'] = _basicAuthHeader(identifier, secret);
    } else {
      // The ID is required for this request any time basic auth isn't being
      // used, even if there's no actual client authentication to be done.
      body['client_id'] = identifier;
      if (secret != null) body['client_secret'] = secret;
    }

    var response =
        await _httpClient!.post(tokenEndpoint, headers: headers, body: body);

    var credentials = _handleAccessTokenResponse(
      response,
      tokenEndpoint,
      startTime,
      _scopes,
      _delimiter,
      getParameters: _getParameters,
    );
    return _Client(
      credentials,
      identifier: identifier,
      secret: secret,
      basicAuth: _basicAuth,
      httpClient: _httpClient,
      onCredentialsRefreshed: _onCredentialsRefreshed,
    );
  }

  // Randomly generate a 128 character string to be used as the PKCE code
  // verifier.
  static String _createCodeVerifier() => List.generate(
        128,
        (i) => _charset[Random.secure().nextInt(_charset.length)],
      ).join();

  /// Closes the grant and frees its resources.
  ///
  /// This will close the underlying HTTP client, which is shared by the
  /// [_Client] created by this grant, so it's not safe to close the grant and
  /// continue using the client.
  void close() {
    _httpClient?.close();
    _httpClient = null;
  }
}

/// States that [_AuthorizationCodeGrant] can be in.
enum _State {
  initial('initial'),
  awaitingResponse('awaiting response'),
  finished('finished');

  final String _name;

  const _State(this._name);

  @override
  String toString() => _name;
}

/// An exception raised when OAuth2 authorization fails.
class _AuthorizationException implements Exception {
  /// The name of the error.
  ///
  /// Possible names are enumerated in [the spec][].
  ///
  /// [the spec]: http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-5.2
  final String error;

  /// The description of the error, provided by the server.
  ///
  /// May be `null` if the server provided no description.
  final String? description;

  /// A URL for a page that describes the error in more detail, provided by the
  /// server.
  ///
  /// May be `null` if the server provided no URL.
  final Uri? uri;

  /// Creates an AuthorizationException.
  _AuthorizationException(this.error, this.description, this.uri);

  /// Provides a string description of the AuthorizationException.
  @override
  String toString() {
    var header = 'OAuth authorization error ($error)';
    if (description != null) {
      header = '$header: $description';
    } else if (uri != null) {
      header = '$header: $uri';
    }
    return '$header.';
  }
}

/// An OAuth2 client.
///
/// This acts as a drop-in replacement for an [http.Client], while sending
/// OAuth2 authorization credentials along with each request.
///
/// The client also automatically refreshes its credentials if possible. When it
/// makes a request, if its credentials are expired, it will first refresh them.
/// This means that any request may throw an [_AuthorizationException] if the
/// refresh is not authorized for some reason, a [FormatException] if the
/// authorization server provides ill-formatted responses, or an
/// [_ExpirationException] if the credentials are expired and can't be refreshed.
///
/// The client will also throw an [_AuthorizationException] if the resource
/// server returns a 401 response with a WWW-Authenticate header indicating that
/// the current credentials are invalid.
///
/// If you already have a set of [Credentials], you can construct a [_Client]
/// directly. However, in order to first obtain the credentials, you must
/// authorize. At the time of writing, the only authorization method this
/// library supports is [_AuthorizationCodeGrant].
class _Client extends http.BaseClient {
  /// The client identifier for this client.
  ///
  /// The authorization server will issue each client a separate client
  /// identifier and secret, which allows the server to tell which client is
  /// accessing it. Some servers may also have an anonymous identifier/secret
  /// pair that any client may use.
  ///
  /// This is usually global to the program using this library.
  final String? identifier;

  /// The client secret for this client.
  ///
  /// The authorization server will issue each client a separate client
  /// identifier and secret, which allows the server to tell which client is
  /// accessing it. Some servers may also have an anonymous identifier/secret
  /// pair that any client may use.
  ///
  /// This is usually global to the program using this library.
  ///
  /// Note that clients whose source code or binary executable is readily
  /// available may not be able to make sure the client secret is kept a secret.
  /// This is fine; OAuth2 servers generally won't rely on knowing with
  /// certainty that a client is who it claims to be.
  final String? secret;

  /// The credentials this client uses to prove to the resource server that it's
  /// authorized.
  ///
  /// This may change from request to request as the credentials expire and the
  /// client refreshes them automatically.
  Credentials get credentials => _credentials;
  Credentials _credentials;

  /// Callback to be invoked whenever the credentials refreshed.
  final _CredentialsRefreshedCallback? _onCredentialsRefreshed;

  /// Whether to use HTTP Basic authentication for authorizing the client.
  final bool _basicAuth;

  /// The underlying HTTP client.
  http.Client? _httpClient;

  /// Creates a new client from a pre-existing set of credentials.
  ///
  /// When authorizing a client for the first time, you should use
  /// [_AuthorizationCodeGrant] or [_resourceOwnerPasswordGrant] instead of
  /// constructing a [_Client] directly.
  ///
  /// [httpClient] is the underlying client that this forwards requests to after
  /// adding authorization credentials to them.
  ///
  /// Throws an [ArgumentError] if [secret] is passed without [identifier].
  _Client(
    this._credentials, {
    this.identifier,
    this.secret,
    _CredentialsRefreshedCallback? onCredentialsRefreshed,
    bool basicAuth = true,
    http.Client? httpClient,
  })  : _basicAuth = basicAuth,
        _onCredentialsRefreshed = onCredentialsRefreshed,
        _httpClient = httpClient ?? http.Client() {
    if (identifier == null && secret != null) {
      throw ArgumentError('secret may not be passed without identifier.');
    }
  }

  /// Sends an HTTP request with OAuth2 authorization credentials attached.
  ///
  /// This will also automatically refresh this client's [Credentials] before
  /// sending the request if necessary.
  @override
  Future<http.StreamedResponse> send(http.BaseRequest request) async {
    if (credentials.isExpired) {
      if (!credentials.canRefresh) throw _ExpirationException(credentials);
      await refreshCredentials();
    }

    request.headers['authorization'] = 'Bearer ${credentials.accessToken}';
    var response = await _httpClient!.send(request);

    if (response.statusCode != 401) return response;
    if (!response.headers.containsKey('www-authenticate')) return response;

    List<AuthenticationChallenge> challenges;
    try {
      challenges = AuthenticationChallenge.parseHeader(
        response.headers['www-authenticate']!,
      );
    } on FormatException {
      return response;
    }

    var challenge = challenges
        .firstWhereOrNull((challenge) => challenge.scheme == 'bearer');
    if (challenge == null) return response;

    var params = challenge.parameters;
    if (!params.containsKey('error')) return response;

    throw _AuthorizationException(
      params['error']!,
      params['error_description'],
      params['error_uri'] == null ? null : Uri.parse(params['error_uri']!),
    );
  }

  /// A [Future] used to track whether [refreshCredentials] is running.
  Future<Credentials>? _refreshingFuture;

  /// Explicitly refreshes this client's credentials. Returns this client.
  ///
  /// This will throw a [StateError] if the [Credentials] can't be refreshed, an
  /// [_AuthorizationException] if refreshing the credentials fails, or a
  /// [FormatException] if the authorization server returns invalid responses.
  ///
  /// You may request different scopes than the default by passing in
  /// [newScopes]. These must be a subset of the scopes in the
  /// [Credentials.scopes] field of [_Client.credentials].
  Future<_Client> refreshCredentials([List<String>? newScopes]) async {
    if (!credentials.canRefresh) {
      var prefix = 'OAuth credentials';
      if (credentials.isExpired) prefix = '$prefix have expired and';
      throw StateError("$prefix can't be refreshed.");
    }

    // To make sure that only one refresh happens when credentials are expired
    // we track it using the [_refreshingFuture]. And also make sure that the
    // _onCredentialsRefreshed callback is only called once.
    if (_refreshingFuture == null) {
      try {
        _refreshingFuture = credentials.refresh(
          identifier: identifier,
          secret: secret,
          newScopes: newScopes,
          basicAuth: _basicAuth,
          httpClient: _httpClient,
        );
        _credentials = await _refreshingFuture!;
        _onCredentialsRefreshed?.call(_credentials);
      } finally {
        _refreshingFuture = null;
      }
    } else {
      await _refreshingFuture;
    }

    return this;
  }

  /// Closes this client and its underlying HTTP client.
  @override
  void close() {
    _httpClient?.close();
    _httpClient = null;
  }
}

/// Type of the callback when credentials are refreshed.
typedef _CredentialsRefreshedCallback = void Function(Credentials);

/// Credentials that prove that a client is allowed to access a resource on the
/// resource owner's behalf.
///
/// These credentials are long-lasting and can be safely persisted across
/// multiple runs of the program.
///
/// Many authorization servers will attach an expiration date to a set of
/// credentials, along with a token that can be used to refresh the credentials
/// once they've expired. The [_Client] will automatically refresh its
/// credentials when necessary. It's also possible to explicitly refresh them
/// via [_Client.refreshCredentials] or [Credentials.refresh].
///
/// Note that a given set of credentials can only be refreshed once, so be sure
/// to save the refreshed credentials for future use.
class Credentials {
  /// A [String] used to separate scopes; defaults to `" "`.
  String _delimiter;

  /// The token that is sent to the resource server to prove the authorization
  /// of a client.
  final String accessToken;

  /// The token that is sent to the authorization server to refresh the
  /// credentials.
  ///
  /// This may be `null`, indicating that the credentials can't be refreshed.
  final String? refreshToken;

  /// The token that is received from the authorization server to enable
  /// End-Users to be Authenticated, contains Claims, represented as a
  /// JSON Web Token (JWT).
  ///
  /// This may be `null`, indicating that the 'openid' scope was not
  /// requested (or not supported).
  ///
  /// [spec]: https://openid.net/specs/openid-connect-core-1_0.html#IDToken
  final String? idToken;

  /// The URL of the authorization server endpoint that's used to refresh the
  /// credentials.
  ///
  /// This may be `null`, indicating that the credentials can't be refreshed.
  final Uri? tokenEndpoint;

  /// The specific permissions being requested from the authorization server.
  ///
  /// The scope strings are specific to the authorization server and may be
  /// found in its documentation.
  final List<String>? scopes;

  /// The date at which these credentials will expire.
  ///
  /// This is likely to be a few seconds earlier than the server's idea of the
  /// expiration date.
  final DateTime? expiration;

  /// The function used to parse parameters from a host's response.
  final _GetParameters _getParameters;

  /// Whether or not these credentials have expired.
  ///
  /// Note that it's possible the credentials will expire shortly after this is
  /// called. However, since the client's expiration date is kept a few seconds
  /// earlier than the server's, there should be enough leeway to rely on this.
  bool get isExpired {
    var expiration = this.expiration;
    return expiration != null && DateTime.now().isAfter(expiration);
  }

  /// Whether it's possible to refresh these credentials.
  bool get canRefresh => refreshToken != null && tokenEndpoint != null;

  /// Creates a new set of credentials.
  ///
  /// This class is usually not constructed directly; rather, it's accessed via
  /// [_Client.credentials] after a [_Client] is created by
  /// [_AuthorizationCodeGrant]. Alternately, it may be loaded from a serialized
  /// form via [Credentials.fromJson].
  ///
  /// The scope strings will be separated by the provided [delimiter]. This
  /// defaults to `" "`, the OAuth2 standard, but some APIs (such as Facebook's)
  /// use non-standard delimiters.
  ///
  /// By default, this follows the OAuth2 spec and requires the server's
  /// responses to be in JSON format. However, some servers return non-standard
  /// response formats, which can be parsed using the [getParameters] function.
  ///
  /// This function is passed the `Content-Type` header of the response as well
  /// as its body as a UTF-8-decoded string. It should return a map in the same
  /// format as the [standard JSON response][].
  ///
  /// [standard JSON response]: https://tools.ietf.org/html/rfc6749#section-5.1
  Credentials(
    this.accessToken, {
    this.refreshToken,
    this.idToken,
    this.tokenEndpoint,
    Iterable<String>? scopes,
    this.expiration,
    String? delimiter,
    Map<String, dynamic> Function(MediaType? mediaType, String body)?
        getParameters,
  })  : scopes = UnmodifiableListView(
          // Explicitly type-annotate the list literal to work around
          // sdk#24202.
          scopes == null ? <String>[] : scopes.toList(),
        ),
        _delimiter = delimiter ?? ' ',
        _getParameters = getParameters ?? parseJsonParameters;

  /// Loads a set of credentials from a JSON-serialized form.
  ///
  /// Throws a [FormatException] if the JSON is incorrectly formatted.
  factory Credentials.fromJson(String json) {
    void validate(bool condition, message) {
      if (condition) return;
      throw FormatException('Failed to load credentials: $message.\n\n$json');
    }

    dynamic parsed;
    try {
      parsed = jsonDecode(json);
    } on FormatException {
      validate(false, 'invalid JSON');
    }

    validate(parsed is Map, 'was not a JSON map');

    parsed = parsed as Map;
    validate(
      parsed.containsKey('accessToken'),
      'did not contain required field "accessToken"',
    );
    validate(
      parsed['accessToken'] is String,
      'required field "accessToken" was not a string, was '
      '${parsed["accessToken"]}',
    );

    for (var stringField in ['refreshToken', 'idToken', 'tokenEndpoint']) {
      var value = parsed[stringField];
      validate(
        value == null || value is String,
        'field "$stringField" was not a string, was "$value"',
      );
    }

    var scopes = parsed['scopes'];
    validate(
      scopes == null || scopes is List,
      'field "scopes" was not a list, was "$scopes"',
    );

    var tokenEndpoint = parsed['tokenEndpoint'];
    Uri? tokenEndpointUri;
    if (tokenEndpoint != null) {
      tokenEndpointUri = Uri.parse(tokenEndpoint as String);
    }

    var expiration = parsed['expiration'];
    DateTime? expirationDateTime;
    if (expiration != null) {
      validate(
        expiration is int,
        'field "expiration" was not an int, was "$expiration"',
      );
      expiration = expiration as int;
      expirationDateTime = DateTime.fromMillisecondsSinceEpoch(expiration);
    }

    return Credentials(
      parsed['accessToken'] as String,
      refreshToken: parsed['refreshToken'] as String?,
      idToken: parsed['idToken'] as String?,
      tokenEndpoint: tokenEndpointUri,
      scopes: (scopes as List).map((scope) => scope as String),
      expiration: expirationDateTime,
    );
  }

  /// Serializes a set of credentials to JSON.
  ///
  /// Nothing is guaranteed about the output except that it's valid JSON and
  /// compatible with [Credentials.toJson].
  String toJson() => jsonEncode({
        'accessToken': accessToken,
        'refreshToken': refreshToken,
        'idToken': idToken,
        'tokenEndpoint': tokenEndpoint?.toString(),
        'scopes': scopes,
        'expiration': expiration?.millisecondsSinceEpoch,
      });

  /// Returns a new set of refreshed credentials.
  ///
  /// See [_Client.identifier] and [_Client.secret] for explanations of those
  /// parameters.
  ///
  /// You may request different scopes than the default by passing in
  /// [newScopes]. These must be a subset of [scopes].
  ///
  /// This throws an [ArgumentError] if [secret] is passed without [identifier],
  /// a [StateError] if these credentials can't be refreshed, an
  /// [_AuthorizationException] if refreshing the credentials fails, or a
  /// [FormatException] if the authorization server returns invalid responses.
  Future<Credentials> refresh({
    String? identifier,
    String? secret,
    Iterable<String>? newScopes,
    bool basicAuth = true,
    http.Client? httpClient,
  }) async {
    var scopes = this.scopes;
    if (newScopes != null) scopes = newScopes.toList();
    scopes ??= [];
    httpClient ??= http.Client();

    if (identifier == null && secret != null) {
      throw ArgumentError('secret may not be passed without identifier.');
    }

    var startTime = DateTime.now();
    var tokenEndpoint = this.tokenEndpoint;
    if (refreshToken == null) {
      throw StateError("Can't refresh credentials without a refresh "
          'token.');
    } else if (tokenEndpoint == null) {
      throw StateError("Can't refresh credentials without a token "
          'endpoint.');
    }

    var headers = <String, String>{};

    var body = {'grant_type': 'refresh_token', 'refresh_token': refreshToken};
    if (scopes.isNotEmpty) body['scope'] = scopes.join(_delimiter);

    if (basicAuth && secret != null) {
      headers['Authorization'] = _basicAuthHeader(identifier!, secret);
    } else {
      if (identifier != null) body['client_id'] = identifier;
      if (secret != null) body['client_secret'] = secret;
    }

    var response =
        await httpClient.post(tokenEndpoint, headers: headers, body: body);
    var credentials = _handleAccessTokenResponse(
      response,
      tokenEndpoint,
      startTime,
      scopes,
      _delimiter,
      getParameters: _getParameters,
    );

    // The authorization server may issue a new refresh token. If it doesn't,
    // we should re-use the one we already have.
    if (credentials.refreshToken != null) return credentials;
    return Credentials(
      credentials.accessToken,
      refreshToken: refreshToken,
      idToken: credentials.idToken,
      tokenEndpoint: credentials.tokenEndpoint,
      scopes: credentials.scopes,
      expiration: credentials.expiration,
    );
  }
}

/// An exception raised when attempting to use expired OAuth2 credentials.
class _ExpirationException implements Exception {
  /// The expired credentials.
  final Credentials credentials;

  /// Creates an ExpirationException.
  _ExpirationException(this.credentials);

  /// Provides a string description of the ExpirationException.
  @override
  String toString() =>
      "OAuth2 credentials have expired and can't be refreshed.";
}

/// The amount of time to add as a "grace period" for credential expiration.
///
/// This allows credential expiration checks to remain valid for a reasonable
/// amount of time.
const _expirationGrace = Duration(seconds: 10);

/// Handles a response from the authorization server that contains an access
/// token.
///
/// This response format is common across several different components of the
/// OAuth2 flow.
///
/// By default, this follows the OAuth2 spec and requires the server's responses
/// to be in JSON format. However, some servers return non-standard response
/// formats, which can be parsed using the [getParameters] function.
///
/// This function is passed the `Content-Type` header of the response as well as
/// its body as a UTF-8-decoded string. It should return a map in the same
/// format as the [standard JSON response][].
///
/// [standard JSON response]: https://tools.ietf.org/html/rfc6749#section-5.1
Credentials _handleAccessTokenResponse(
  http.Response response,
  Uri tokenEndpoint,
  DateTime startTime,
  List<String>? scopes,
  String delimiter, {
  Map<String, dynamic> Function(MediaType? contentType, String body)?
      getParameters,
}) {
  getParameters ??= parseJsonParameters;

  try {
    if (response.statusCode != 200) {
      _handleErrorResponse(response, tokenEndpoint, getParameters);
    }

    var contentTypeString = response.headers['content-type'];
    if (contentTypeString == null) {
      throw const FormatException('Missing Content-Type string.');
    }

    var parameters =
        getParameters(MediaType.parse(contentTypeString), response.body);

    for (var requiredParameter in ['access_token', 'token_type']) {
      if (!parameters.containsKey(requiredParameter)) {
        throw FormatException(
          'did not contain required parameter "$requiredParameter"',
        );
      } else if (parameters[requiredParameter] is! String) {
        throw FormatException(
            'required parameter "$requiredParameter" was not a string, was '
            '"${parameters[requiredParameter]}"');
      }
    }

    // TODO(nweiz): support the "mac" token type
    // (http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01)
    if ((parameters['token_type'] as String).toLowerCase() != 'bearer') {
      throw FormatException(
        '"$tokenEndpoint": unknown token type "${parameters['token_type']}"',
      );
    }

    var expiresIn = parameters['expires_in'];
    if (expiresIn != null) {
      if (expiresIn is String) {
        try {
          expiresIn = double.parse(expiresIn).toInt();
        } on FormatException {
          throw FormatException(
            'parameter "expires_in" could not be parsed as in, was: "$expiresIn"',
          );
        }
      } else if (expiresIn is! int) {
        throw FormatException(
          'parameter "expires_in" was not an int, was: "$expiresIn"',
        );
      }
    }

    for (var name in ['refresh_token', 'id_token', 'scope']) {
      var value = parameters[name];
      if (value != null && value is! String) {
        throw FormatException(
          'parameter "$name" was not a string, was "$value"',
        );
      }
    }

    var scope = parameters['scope'] as String?;
    if (scope != null) scopes = scope.split(delimiter);

    var expiration = expiresIn == null
        ? null
        : startTime.add(Duration(seconds: expiresIn as int) - _expirationGrace);

    return Credentials(
      parameters['access_token'] as String,
      refreshToken: parameters['refresh_token'] as String?,
      idToken: parameters['id_token'] as String?,
      tokenEndpoint: tokenEndpoint,
      scopes: scopes,
      expiration: expiration,
    );
  } on FormatException catch (e) {
    throw FormatException('Invalid OAuth response for "$tokenEndpoint": '
        '${e.message}.\n\n${response.body}');
  }
}

/// Throws the appropriate exception for an error response from the
/// authorization server.
void _handleErrorResponse(
  http.Response response,
  Uri tokenEndpoint,
  _GetParameters getParameters,
) {
  // OAuth2 mandates a 400 or 401 response code for access token error
  // responses. If it's not a 400 reponse, the server is either broken or
  // off-spec.
  if (response.statusCode != 400 && response.statusCode != 401) {
    var reason = '';
    var reasonPhrase = response.reasonPhrase;
    if (reasonPhrase != null && reasonPhrase.isNotEmpty) {
      reason = ' $reasonPhrase';
    }
    throw FormatException('OAuth request for "$tokenEndpoint" failed '
        'with status ${response.statusCode}$reason.\n\n${response.body}');
  }

  var contentTypeString = response.headers['content-type'];
  var contentType =
      contentTypeString == null ? null : MediaType.parse(contentTypeString);

  var parameters = getParameters(contentType, response.body);

  if (!parameters.containsKey('error')) {
    throw const FormatException('did not contain required parameter "error"');
  } else if (parameters['error'] is! String) {
    throw FormatException('required parameter "error" was not a string, was '
        '"${parameters["error"]}"');
  }

  for (var name in ['error_description', 'error_uri']) {
    var value = parameters[name];

    if (value != null && value is! String) {
      throw FormatException('parameter "$name" was not a string, was "$value"');
    }
  }

  var uriString = parameters['error_uri'] as String?;
  var uri = uriString == null ? null : Uri.parse(uriString);
  var description = parameters['error_description'] as String?;
  throw _AuthorizationException(
    parameters['error'] as String,
    description,
    uri,
  );
}

/// The type of a callback that parses parameters from an HTTP response.
typedef _GetParameters = Map<String, dynamic> Function(
  MediaType? contentType,
  String body,
);

/// Parses parameters from a response with a JSON body, as per the
/// [OAuth2 spec][].
///
/// [OAuth2 spec]: https://tools.ietf.org/html/rfc6749#section-5.1
Map<String, dynamic> parseJsonParameters(MediaType? contentType, String body) {
  // The spec requires a content-type of application/json, but some endpoints
  // (e.g. Dropbox) serve it as text/javascript instead.
  if (contentType == null ||
      (contentType.mimeType != 'application/json' &&
          contentType.mimeType != 'text/javascript')) {
    throw FormatException(
      'Content-Type was "$contentType", expected "application/json"',
    );
  }

  var untypedParameters = jsonDecode(body);
  if (untypedParameters is Map<String, dynamic>) {
    return untypedParameters;
  }

  throw FormatException('Parameters must be a map, was "$untypedParameters"');
}

/// Adds additional query parameters to [url], overwriting the original
/// parameters if a name conflict occurs.
Uri _addQueryParameters(Uri url, Map<String, String> parameters) => url.replace(
      queryParameters: Map.from(url.queryParameters)..addAll(parameters),
    );

String _basicAuthHeader(String identifier, String secret) {
  var userPass = '${Uri.encodeFull(identifier)}:${Uri.encodeFull(secret)}';
  return 'Basic ${base64Encode(ascii.encode(userPass))}';
}
