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

import 'dart:async';
import 'dart:io';
import 'dart:uri';

// TODO(nweiz): Make this a "package:" URL, or something nicer than this.
import '../../pkg/oauth2/lib/oauth2.dart';
import '../../pkg/path/lib/path.dart' as path;

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

export '../../pkg/oauth2/lib/oauth2.dart';

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

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

/// 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.
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 = ['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(SystemCache cache) {
  _credentials = null;
  var credentialsFile = _credentialsFile(cache);
  if (!fileExists(credentialsFile)) return;

  deleteFile(credentialsFile);
}

/// Asynchronously passes an OAuth2 [Client] to [fn], and closes the client when
/// the [Future] returned by [fn] completes.
///
/// 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 withClient(SystemCache cache, Future fn(Client client)) {
  return _getClient(cache).then((client) {
    var completer = new Completer();
    return fn(client).whenComplete(() {
      client.close();
      // Be sure to save the credentials even when an error happens.
      _saveCredentials(cache, client.credentials);
    });
  }).catchError((asyncError) {
    if (asyncError.error is ExpirationException) {
      log.error("Pub's authorization to upload packages has expired and "
          "can't be automatically refreshed.");
      return withClient(cache, fn);
    } else if (asyncError.error is AuthorizationException) {
      var message = "OAuth2 authorization failed";
      if (asyncError.error.description != null) {
        message = "$message (${asyncError.error.description})";
      }
      log.error("$message.");
      clearCredentials(cache);
      return withClient(cache, fn);
    } else {
      throw asyncError;
    }
  });
}

/// 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(SystemCache cache) {
  return defer(() {
    var credentials = _loadCredentials(cache);
    if (credentials == null) return _authorize();

    var client = new Client(_identifier, _secret, credentials,
        httpClient: httpClient);
    _saveCredentials(cache, 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] will complete to null.
Credentials _loadCredentials(SystemCache cache) {
  log.fine('Loading OAuth2 credentials.');

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

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

    var credentials = new 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) {
    log.error('Warning: could not load the saved OAuth2 credentials: $e\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(SystemCache cache, Credentials credentials) {
  log.fine('Saving OAuth2 credentials.');
  _credentials = credentials;
  var credentialsPath = _credentialsFile(cache);
  ensureDir(path.dirname(credentialsPath));
  writeTextFile(credentialsPath, credentials.toJson(), dontLogContents: true);
}

/// The path to the file in which the user's OAuth2 credentials are stored.
String _credentialsFile(SystemCache cache) =>
    path.join(cache.rootDir, 'credentials.json');

/// Gets the user to authorize pub as a client of pub.dartlang.org via oauth2.
/// Returns a Future that will complete to a fully-authorized [Client].
Future<Client> _authorize() {
  // Allow the tests to inject their own token endpoint URL.
  var tokenEndpoint = Platform.environment['_PUB_TEST_TOKEN_ENDPOINT'];
  if (tokenEndpoint != null) {
    tokenEndpoint = Uri.parse(tokenEndpoint);
  } else {
    tokenEndpoint = _tokenEndpoint;
  }

  var grant = new AuthorizationCodeGrant(
      _identifier,
      _secret,
      _authorizationEndpoint,
      tokenEndpoint,
      httpClient: httpClient);

  // 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.
  return HttpServer.bind('127.0.0.1', 0).then((server) {
    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...');
    return server.first.then((request) {
      var response = request.response;
      if (request.uri.path == "/") {
        log.message('Authorization received, processing...');
        var queryString = request.uri.query;
        if (queryString == null) queryString = '';
        response.statusCode = 302;
        response.headers.set('location',
                             'http://pub.dartlang.org/authorized');
        response.close();
        return grant.handleAuthorizationResponse(queryToMap(queryString))
        .then((client) {
          server.close();
          return client;
        });
      } else {
        response.statusCode = 404;
        response.close();
      }
    });
  })
  .then((client) {
    log.message('Successfully authorized.\n');
    return client;
  });
}
