// 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.

library oauth2_client;

import 'dart:async';

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

import 'authorization_exception.dart';
import 'credentials.dart';
import 'expiration_exception.dart';
import 'utils.dart';

// TODO(nweiz): Add an onCredentialsRefreshed event once we have some event
// infrastructure.
/// 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;

  /// 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] instead of constructing a [Client] directly.
  ///
  /// [httpClient] is the underlying client that this forwards requests to after
  /// adding authorization credentials to them.
  Client(
      this.identifier,
      this.secret,
      this._credentials,
      {http.Client httpClient})
    : _httpClient = httpClient == null ? new http.Client() : httpClient;

  /// Sends an HTTP request with OAuth2 authorization credentials attached. This
  /// will also automatically refresh this client's [Credentials] before sending
  /// the request if necessary.
  Future<http.StreamedResponse> send(http.BaseRequest request) {
    return async.then((_) {
      if (!credentials.isExpired) return new Future.value();
      if (!credentials.canRefresh) throw new ExpirationException(credentials);
      return refreshCredentials();
    }).then((_) {
      request.headers['authorization'] = "Bearer ${credentials.accessToken}";
      return _httpClient.send(request);
    }).then((response) {
      if (response.statusCode != 401 ||
          !response.headers.containsKey('www-authenticate')) {
        return response;
      }

      var authenticate;
      try {
        authenticate = new AuthenticateHeader.parse(
            response.headers['www-authenticate']);
      } on FormatException catch (e) {
        return response;
      }

      if (authenticate.scheme != 'bearer') return response;

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

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

  /// 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
  /// [FormatError] 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]) {
    return async.then((_) {
      if (!credentials.canRefresh) {
        var prefix = "OAuth credentials";
        if (credentials.isExpired) prefix = "$prefix have expired and";
        throw new StateError("$prefix can't be refreshed.");
      }

      return credentials.refresh(identifier, secret,
          newScopes: newScopes, httpClient: _httpClient);
    }).then((credentials) {
      _credentials = credentials;
      return this;
    });
  }

  /// Closes this client and its underlying HTTP client.
  void close() {
    if (_httpClient != null) _httpClient.close();
    _httpClient = null;
  }
}
