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

import '../authentication/credential.dart';
import '../command.dart';
import '../command_runner.dart';
import '../exceptions.dart';
import '../io.dart';
import '../log.dart' as log;
import '../platform_info.dart';
import '../source/hosted.dart';
import '../utils.dart';

/// Handles the `token add` pub command.
class TokenAddCommand extends PubCommand {
  @override
  String get name => 'add';
  @override
  String get description => '''
Add an authentication token for a package repository.

The token will be used for authorizing against <hosted-url> both when
retrieving dependencies and for publishing.

Tokens are stored in ${tokenStore.tokensFile}.

This command will prompt for the secret token over stdin.
(Unless `--env-var` is used).

For interactive authorization against pub.dev, use `$topLevelProgram pub login`.''';
  @override
  String get argumentsDescription => '[options] <hosted-url>';

  @override
  String get docUrl => 'https://dart.dev/tools/pub/cmd/pub-token';

  String? get envVar => argResults.option('env-var');

  TokenAddCommand() {
    argParser.addOption(
      'env-var',
      help:
          'Read the secret token from this environment variable when '
          'making requests.',
      valueHelp: 'VARIABLE',
    );
  }

  @override
  Future<void> runProtected() async {
    if (argResults.rest.isEmpty) {
      usageException(
        'The [hosted-url] for a package repository must be given.',
      );
    } else if (argResults.rest.length > 1) {
      usageException('Takes only a single argument.');
    }
    final rawHostedUrl = argResults.rest.first;

    try {
      final hostedUrl = validateAndNormalizeHostedUrl(rawHostedUrl);
      final isLocalhost = [
        'localhost',
        '127.0.0.1',
        '::1',
      ].contains(hostedUrl.host);
      if (!hostedUrl.isScheme('HTTPS') && !isLocalhost) {
        throw const FormatException(
          'url must be https://, '
          'insecure repositories cannot use authentication.',
        );
      }

      if (envVar == null) {
        await _addTokenFromStdin(hostedUrl);
      } else {
        await _addEnvVarToken(hostedUrl, envVar!);
      }
    } on FormatException catch (e) {
      usageException(
        'Invalid [hosted-url]: "$rawHostedUrl"\n'
        '${e.message}',
      );
    }
  }

  Future<void> _addTokenFromStdin(Uri hostedUrl) async {
    final token = await stdinPrompt('Enter secret token:', echoMode: false);
    if (token.isEmpty) {
      usageException('Token is not provided.');
    }

    if (!Credential.isValidBearerToken(token)) {
      dataError(
        'The entered token is not a valid Bearer token. '
        'A token may only contain `a-zA-Z0-9._~+/=-`',
      );
    }

    tokenStore.addCredential(Credential.token(hostedUrl, token));
    log.message(
      'Requests to "$hostedUrl" will now be authenticated using the secret '
      'token.',
    );
  }

  Future<void> _addEnvVarToken(Uri hostedUrl, String envVar) async {
    if (envVar.isEmpty) {
      usageException('Cannot use the empty string as --env-var');
    }

    // Environment variable names on Windows [1] and UNIX [2] cannot contain
    // equal signs.
    // [1] https://docs.microsoft.com/en-us/windows/win32/procthread/environment-variables
    // [2] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
    if (envVar.contains('=')) {
      throw DataException(
        'Environment variable name --env-var="$envVar" cannot contain "=", the '
        'equals sign is not allowed in environment variable names.',
      );
    }

    // Help the user if they typed something that is unlikely to be correct.
    // This could happen if you include $, whitespace, quotes or accidentally
    // dereference the environment variable instead.
    if (!RegExp(r'^[A-Z_][A-Z0-9_]*$').hasMatch(envVar)) {
      log.warning(
        'The environment variable name --env-var="$envVar" does not use '
        'uppercase characters A-Z, 0-9 and underscore. This is unusual for '
        'environment variable names.\n'
        'Check that you meant to use the environment variable name: "$envVar".',
      );
    }

    tokenStore.addCredential(Credential.env(hostedUrl, envVar));
    log.message(
      'Requests to "$hostedUrl" will now be authenticated using the secret '
      'token stored in the environment variable "$envVar".',
    );

    if (!platform.environment.containsKey(envVar)) {
      // If environment variable doesn't exist when
      // pub token add <hosted-url> --env-var <ENV_VAR> is called, we should
      // print a warning.
      log.warning('Environment variable "$envVar" is not defined.');
    }
  }
}
