// 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 handle_access_token_response;

import 'dart:io';
import 'dart:json' as JSON;
import 'dart:uri';

import '../../../http/lib/http.dart' as http;

import 'credentials.dart';
import 'authorization_exception.dart';

/// The amount of time, in seconds, to add as a "grace period" for credential
/// expiration. This allows credential expiration checks to remain valid for a
/// reasonable amount of time.
const _EXPIRATION_GRACE = 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.
Credentials handleAccessTokenResponse(
    http.Response response,
    Uri tokenEndpoint,
    DateTime startTime,
    List<String> scopes) {
  if (response.statusCode != 200) _handleErrorResponse(response, tokenEndpoint);

  void validate(bool condition, String message) =>
    _validate(response, tokenEndpoint, condition, message);

  var contentType = response.headers['content-type'];
  if (contentType != null) {
    contentType = new ContentType.fromString(contentType);
  }
  validate(contentType != null && contentType.value == "application/json",
      'content-type was "$contentType", expected "application/json"');

  var parameters;
  try {
    parameters = JSON.parse(response.body);
  } catch (e) {
    // TODO(nweiz): narrow this catch clause once issue 6775 is fixed.
    validate(false, 'invalid JSON');
  }

  for (var requiredParameter in ['access_token', 'token_type']) {
    validate(parameters.containsKey(requiredParameter),
        'did not contain required parameter "$requiredParameter"');
    validate(parameters[requiredParameter] is String,
        '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)
  validate(parameters['token_type'].toLowerCase() == 'bearer',
      '"$tokenEndpoint": unknown token type "${parameters['token_type']}"');

  var expiresIn = parameters['expires_in'];
  validate(expiresIn == null || expiresIn is int,
      'parameter "expires_in" was not an int, was "$expiresIn"');

  for (var name in ['refresh_token', 'scope']) {
    var value = parameters[name];
    validate(value == null || value is String,
        'parameter "$name" was not a string, was "$value"');
  }

  var scope = parameters['scope'];
  if (scope != null) scopes = scope.split(" ");

  var expiration = expiresIn == null ? null :
      startTime.add(new Duration(seconds: expiresIn - _EXPIRATION_GRACE));

  return new Credentials(
      parameters['access_token'],
      parameters['refresh_token'],
      tokenEndpoint,
      scopes,
      expiration);
}

/// Throws the appropriate exception for an error response from the
/// authorization server.
void _handleErrorResponse(http.Response response, Uri tokenEndpoint) {
  void validate(bool condition, String message) =>
    _validate(response, tokenEndpoint, condition, message);

  // 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 = '';
    if (response.reasonPhrase != null && !response.reasonPhrase.isEmpty) {
      ' ${response.reasonPhrase}';
    }
    throw new FormatException('OAuth request for "$tokenEndpoint" failed '
        'with status ${response.statusCode}$reason.\n\n${response.body}');
  }

  var contentType = response.headers['content-type'];
  if (contentType != null) {
    contentType = new ContentType.fromString(contentType);
  }
  validate(contentType != null && contentType.value == "application/json",
      'content-type was "$contentType", expected "application/json"');

  var parameters;
  try {
    parameters = JSON.parse(response.body);
  } catch (e) {
    // TODO(nweiz): narrow this catch clause once issue 6775 is fixed.
    validate(false, 'invalid JSON');
  }

  validate(parameters.containsKey('error'),
      'did not contain required parameter "error"');
  validate(parameters["error"] is String,
      'required parameter "error" was not a string, was '
      '"${parameters["error"]}"');

  for (var name in ['error_description', 'error_uri']) {
    var value = parameters[name];
    validate(value == null || value is String,
        'parameter "$name" was not a string, was "$value"');
  }

  var description = parameters['error_description'];
  var uriString = parameters['error_uri'];
  var uri = uriString == null ? null : new Uri.fromString(uriString);
  throw new AuthorizationException(parameters['error'], description, uri);
}

void _validate(
    http.Response response,
    Uri tokenEndpoint,
    bool condition,
    String message) {
  if (condition) return;
  throw new FormatException('Invalid OAuth response for "$tokenEndpoint": '
      '$message.\n\n${response.body}');
}
