// 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:convert';

import 'package:http/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 = ContentType.parse(contentType);
  }
  validate(contentType != null && contentType.value == "application/json",
      'content-type was "$contentType", expected "application/json"');

  var parameters;
  try {
    parameters = JSON.decode(response.body);
  } on FormatException catch (e) {
    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 = ContentType.parse(contentType);
  }
  validate(contentType != null && contentType.value == "application/json",
      'content-type was "$contentType", expected "application/json"');

  var parameters;
  try {
    parameters = JSON.decode(response.body);
  } on FormatException catch (e) {
    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 : Uri.parse(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}');
}
