// Copyright (c) 2021, 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 '../exceptions.dart';
import '../platform_info.dart';
import '../source/hosted.dart';
import '../utils.dart';

/// [Credential] is a structure for storing authentication credentials for
/// third-party pub registries.
///
/// A [Credential] holds a registry [url], and either the [token] itself or the
/// name of an environment variable [env] for looking up the token when
/// authenticating.
///
/// For storing in the pub-tokens.json configuration, a [Credential] can be
/// serialized into and from JSON format structured like this:
///
/// ```json
/// {
///   "url": "https://example.com/",
///   "token": "gjrjo7Tm2F0u64cTsECDq4jBNZYhco"
/// }
/// ```
///
/// or
///
/// ```json
/// {
///   "url": "https://example.com/",
///   "env": "TOKEN_ENV_VAR"
/// }
/// ```
///
/// Unknown JSON properties will be preserved when reencoding.
class Credential {
  /// Internal constructor that's only used by [Credential.fromJson].
  Credential._internal({
    required this.url,
    required this.unknownFields,
    required this.token,
    required this.env,
  });

  /// Create credential that stores clear text token.
  Credential.token(this.url, this.token)
    : env = null,
      unknownFields = const <String, dynamic>{};

  /// Create credential that stores environment variable name that stores token
  /// value.
  Credential.env(this.url, this.env)
    : token = null,
      unknownFields = const <String, dynamic>{};

  /// Deserialize [json] into [Credential] type.
  ///
  /// Throws [FormatException] if [json] is not a valid [Credential].
  factory Credential.fromJson(Map<String, dynamic> json) {
    if (json['url'] is! String) {
      throw const FormatException('Url is not provided for the credential');
    }

    final hostedUrl = validateAndNormalizeHostedUrl(json['url'] as String);

    const knownKeys = {'url', 'token', 'env'};
    final unknownFields = Map.fromEntries(
      json.entries.where((kv) => !knownKeys.contains(kv.key)),
    );

    /// Returns [String] value from [json] at [key] index or `null` if [json]
    /// doesn't contains [key].
    ///
    /// Throws [FormatException] if value type is not [String].
    String? string(String key) {
      if (json.containsKey(key)) {
        if (json[key] is! String) {
          throw FormatException('Provided $key value should be string');
        }
        return json[key] as String;
      }
      return null;
    }

    return Credential._internal(
      url: hostedUrl,
      unknownFields: unknownFields,
      token: string('token'),
      env: string('env'),
    );
  }

  /// Server url which this token authenticates.
  final Uri url;

  /// Authentication token value
  final String? token;

  /// Environment variable name that stores token value
  final String? env;

  /// Unknown fields found in pub-tokens.json. The fields might be created by
  /// the future version of pub tool. We don't want to override them when using
  /// the old SDK.
  final Map<String, dynamic> unknownFields;

  /// Serializes [Credential] into json format.
  Map<String, dynamic> toJson() {
    return <String, dynamic>{
      'url': url.toString(),
      if (token != null) 'token': token,
      if (env != null) 'env': env,
      ...unknownFields,
    };
  }

  /// Returns future that resolves "Authorization" header value used for
  /// authenticating.
  ///
  /// Throws [DataException] if credential is not valid.
  // This method returns future to make sure in future we could use the
  // [Credential] interface for OAuth2.0 authentication too - which requires
  // token rotation (refresh) that's async job.
  Future<String> getAuthorizationHeaderValue() {
    if (!isValid()) {
      throw DataException(
        'Saved credential for "$url" pub repository is not supported by '
        'current version of Dart SDK.',
      );
    }

    final String tokenValue;
    final environment = env;
    if (environment != null) {
      final value = platform.environment[environment];
      if (value == null) {
        dataError(
          'Saved credential for "$url" pub repository requires environment '
          'variable named "$env" but not defined.',
        );
      }
      tokenValue = value;
    } else {
      tokenValue = token!;
    }
    if (!isValidBearerToken(tokenValue)) {
      dataError(
        'Credential token for $url is not a valid Bearer token. '
        'It should match `^[a-zA-Z0-9._~+/=-]+\$`',
      );
    }

    return Future.value('Bearer $tokenValue');
  }

  /// Returns whether or not given [url] could be authenticated using this
  /// credential.
  bool canAuthenticate(String url) {
    return _normalizeUrl(url).startsWith(_normalizeUrl(this.url.toString()));
  }

  /// Returns boolean indicates whether or not the credentials is valid.
  ///
  /// This method might return `false` when a `pub-tokens.json` file created by
  /// future SDK used by pub tool from old SDK.
  // Either [token] or [env] should be defined to be valid.
  bool isValid() => (token == null) ^ (env == null);

  /// Whether [candidate] can be used as a bearer token.
  ///
  /// We limit tokens to be valid bearer tokens according to
  /// https://www.rfc-editor.org/rfc/rfc6750#section-2.1
  static bool isValidBearerToken(String candidate) {
    return RegExp(r'^[a-zA-Z0-9._~+/=-]+$').hasMatch(candidate);
  }

  static String _normalizeUrl(String url) {
    return (url.endsWith('/') ? url : '$url/').toLowerCase();
  }
}
