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

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:http/http.dart' as http;

import '../ascii_tree.dart' as tree;
import '../authentication/client.dart';
import '../command.dart';
import '../command_runner.dart';
import '../exceptions.dart' show DataException;
import '../exit_codes.dart';
import '../http.dart';
import '../io.dart';
import '../log.dart' as log;
import '../oauth2.dart' as oauth2;
import '../path.dart';
import '../platform_info.dart';
import '../pubspec.dart';
import '../solver/type.dart';
import '../source/hosted.dart' show validateAndNormalizeHostedUrl;
import '../source/root.dart';
import '../utils.dart';
import '../validator.dart';

/// Handles the `lish` and `publish` pub commands.
class LishCommand extends PubCommand {
  @override
  String get name => 'publish';
  @override
  String get description => 'Publish the current package to pub.dev.';
  @override
  String get argumentsDescription => '[options]';
  @override
  String get docUrl => 'https://dart.dev/tools/pub/cmd/pub-lish';
  @override
  bool get takesArguments => false;

  /// The URL of the server to which to upload the package.
  Uri computeHost(Pubspec pubspec) {
    // An explicit argument takes precedence.
    if (argResults.wasParsed('server')) {
      try {
        return validateAndNormalizeHostedUrl(
          argResults.optionWithDefault('server'),
        );
      } on FormatException catch (e) {
        usageException('Invalid server: $e');
      }
    }

    // Otherwise, use the one specified in the pubspec.
    final publishTo = pubspec.publishTo;
    if (publishTo != null && publishTo != 'none') {
      try {
        return validateAndNormalizeHostedUrl(publishTo);
      } on FormatException catch (e) {
        throw DataException('Invalid publish_to: $e');
      }
    }

    // Use the default server if nothing else is specified
    return Uri.parse(cache.hosted.defaultUrl);
  }

  /// Whether the publish is just a preview.
  bool get dryRun => argResults.flag('dry-run');

  /// Whether the publish requires confirmation.
  bool get force => argResults.flag('force');

  bool get skipValidation => argResults.flag('skip-validation');

  late final String? _fromArchive = argResults.option('from-archive');
  late final String? _toArchive = argResults.option('to-archive');

  LishCommand() {
    argParser.addFlag(
      'dry-run',
      abbr: 'n',
      negatable: false,
      help: 'Validate but do not publish the package.',
    );
    argParser.addFlag(
      'force',
      abbr: 'f',
      negatable: false,
      help: 'Publish without confirmation if there are no errors.',
    );
    argParser.addFlag(
      'skip-validation',
      negatable: false,
      help:
          'Publish without validation and resolution '
          '(this will ignore errors).',
    );
    argParser.addOption(
      'server',
      help: 'The package server to which to upload this package.',
      hide: true,
    );
    argParser.addOption(
      'to-archive',
      help: 'Create a .tar.gz archive instead of publishing to server',
      valueHelp: '[archive.tar.gz]',
      hide: true,
    );
    argParser.addOption(
      'from-archive',
      help:
          'Publish from a .tar.gz archive instead of current folder. '
          'Implies `--skip-validation`.',
      valueHelp: '[archive.tar.gz]',
      hide: true,
    );

    argParser.addOption(
      'directory',
      abbr: 'C',
      help: 'Run this in the directory <dir>.',
      valueHelp: 'dir',
    );
    argParser.addFlag(
      'ignore-warnings',
      help: 'Do not treat warnings as fatal.',
      negatable: false,
    );
  }

  Future<void> _publishUsingClient(
    List<int> packageBytes,
    http.Client client,
    Uri host,
  ) async {
    Uri? cloudStorageUrl;

    try {
      await log.progress('Uploading', () async {
        /// 1. Initiate upload
        final parametersResponse = await retryForHttp(
          'initiating upload',
          () async {
            final request = http.Request(
              'GET',
              host.resolve('api/packages/versions/new'),
            );
            request.attachPubApiHeaders();
            return await client.fetch(request);
          },
        );
        final parameters = parseJsonResponse(parametersResponse);

        /// 2. Upload package
        final url = _expectField(parameters, 'url', parametersResponse);
        if (url is! String) invalidServerResponse(parametersResponse);
        cloudStorageUrl = Uri.parse(url);
        final uploadResponse = await retryForHttp(
          'uploading package',
          () async {
            // TODO(nweiz): Cloud Storage can provide an XML-formatted error. We
            // should report that error and exit.
            final request = http.MultipartRequest('POST', cloudStorageUrl!);

            final fields = _expectField(
              parameters,
              'fields',
              parametersResponse,
            );
            if (fields is! Map) invalidServerResponse(parametersResponse);
            fields.forEach((key, value) {
              if (value is! String) invalidServerResponse(parametersResponse);
              request.fields[key as String] = value;
            });

            request.followRedirects = false;
            request.files.add(
              http.MultipartFile.fromBytes(
                'file',
                packageBytes,
                filename: 'package.tar.gz',
              ),
            );
            return await client.fetch(request);
          },
        );

        /// 3. Finalize publish
        final location = uploadResponse.headers['location'];
        if (location == null) throw PubHttpResponseException(uploadResponse);
        final finalizeResponse = await retryForHttp(
          'finalizing publish',
          () async {
            final request = http.Request('GET', Uri.parse(location));
            request.attachPubApiHeaders();
            return await client.fetch(request);
          },
        );
        handleJsonSuccess(finalizeResponse);
      });
    } on AuthenticationException catch (error) {
      var msg = '';
      if (error.statusCode == 401) {
        msg +=
            '$host package repository requested authentication!\n'
            'You can provide credentials using:\n'
            '    $topLevelProgram pub token add $host\n';
      }
      if (error.statusCode == 403) {
        msg +=
            'Insufficient permissions to the resource at the $host '
            'package repository.\nYou can modify credentials using:\n'
            '    $topLevelProgram pub token add $host\n';
      }
      if (error.serverMessage != null) {
        msg += '\n${error.serverMessage!}\n';
      }
      dataError(msg + log.red('Authentication failed!'));
    } on PubHttpResponseException catch (error) {
      final url = error.response.request!.url;
      if (url == cloudStorageUrl) {
        handleGCSError(error.response);
        fail(log.red('Failed to upload the package.'));
      } else if (Uri.parse(url.origin) == Uri.parse(host.origin)) {
        handleJsonError(error.response);
      } else {
        rethrow;
      }
    }
  }

  Future<void> _publish(List<int> packageBytes, Uri host) async {
    try {
      final officialPubServers = {
        'https://pub.dev',
        // [validateAndNormalizeHostedUrl] normalizes https://pub.dartlang.org
        // to https://pub.dev, so we don't need to do allow that here.

        // Pub uses oauth2 credentials only for authenticating official pub
        // servers for security purposes (to not expose pub.dev access token to
        // 3rd party servers).
        // For testing publish command we're using mock servers hosted on
        // localhost address which is not a known pub server address. So we
        // explicitly have to define mock servers as official server to test
        // publish command with oauth2 credentials.
        if (runningFromTest &&
            platform.environment.containsKey('_PUB_TEST_DEFAULT_HOSTED_URL'))
          platform.environment['_PUB_TEST_DEFAULT_HOSTED_URL'],
      };

      // Using OAuth2 authentication client for the official pub servers
      final isOfficialServer = officialPubServers.contains(host.toString());
      if (isOfficialServer && !cache.tokenStore.hasCredential(host)) {
        // Using OAuth2 authentication client for the official pub servers, when
        // we don't have an explicit token from [TokenStore] to use instead.
        //
        // This allows us to use `dart pub token add` to inject a token for use
        // with the official servers.
        await oauth2.withClient((client) {
          return _publishUsingClient(packageBytes, client, host);
        });
      } else {
        // For third party servers using bearer authentication client
        await withAuthenticatedClient(cache, host, (client) {
          return _publishUsingClient(packageBytes, client, host);
        });
      }
    } on PubHttpResponseException catch (error) {
      final url = error.response.request!.url;
      if (Uri.parse(url.origin) == Uri.parse(host.origin)) {
        handleJsonError(error.response);
      } else {
        rethrow;
      }
    }
  }

  Future<void> _validateArgs() async {
    if (argResults.wasParsed('server')) {
      await log.errorsOnlyUnlessTerminal(() {
        log.message('''
The --server option is deprecated. Use `publish_to` in your pubspec.yaml or set
the \$PUB_HOSTED_URL environment variable.''');
      });
    }

    if (force && dryRun) {
      usageException('Cannot use both --force and --dry-run.');
    }

    if (_fromArchive != null && _toArchive != null) {
      usageException('Cannot use both --from-archive and --to-archive.');
    }

    if (_fromArchive != null && dryRun) {
      usageException('Cannot use both --from-archive and --dry-run.');
    }

    if (_toArchive != null && force) {
      usageException('Cannot use both --to-archive and --force.');
    }

    if (argResults.wasParsed('ignore-warnings') && !dryRun) {
      usageException('`--ignore-warnings` can only be used with `--dry-run`.');
    }
  }

  Future<_Publication> _publicationFromEntrypoint() async {
    if (!dryRun &&
        _toArchive == null &&
        entrypoint.workPackage.pubspec.isPrivate) {
      dataError(
        'A private package cannot be published.\n'
        'You can enable this by changing the "publish_to" field in your '
        'pubspec.',
      );
    }
    if (skipValidation) {
      log.warning(
        'Running with `skip-validation`. No client-side validation is done.',
      );
    } else {
      await entrypoint.acquireDependencies(SolveType.get);
    }

    // For displaying the layout we only want to explicitly mention non-empty
    // directories, so first we list all files and directories, and then filter
    // any non-empty directories away.
    // For validation it is practical to also maintain the list of files.
    final filesAndDirs = entrypoint.workPackage.listFiles(includeDirs: true);

    final files = <String>[];
    final filesAndEmptyDirs = <String>[];
    for (final entry in filesAndDirs) {
      final stat = statPath(entry);
      if (stat.type == FileSystemEntityType.directory) {
        if (listDir(entry).isEmpty) {
          filesAndEmptyDirs.add(entry);
        }
      } else {
        files.add(entry);
        filesAndEmptyDirs.add(entry);
      }
    }

    log.fine('Archiving and publishing ${entrypoint.workPackage.name}.');

    // Show the package contents so the user can verify they look OK.
    final package = entrypoint.workPackage;
    final host = computeHost(package.pubspec);
    final fileTree = tree.fromFiles(
      filesAndEmptyDirs,
      baseDir: entrypoint.workPackage.dir,
      showFileSizes: true,
    );
    log.message(
      'Publishing ${package.name} ${package.version} to $host:\n$fileTree',
    );

    final packageBytes =
        await createTarGz(
          filesAndDirs,
          baseDir: entrypoint.workPackage.dir,
        ).toBytes();

    final size = readableFileSize(packageBytes.length);
    log.message('\nTotal compressed archive size: $size.\n');

    final validationResult =
        skipValidation ? null : await _validate(packageBytes, files, host);

    if (dryRun) {
      log.message('The server may enforce additional checks.');
    }
    return _Publication(
      packageBytes: packageBytes,
      warningCount: validationResult?.warningsCount ?? 0,
      hintCount: validationResult?.hintsCount ?? 0,
      pubspec: package.pubspec,
    );
  }

  Future<_Publication> _publicationFromArchive(String archive) async {
    final Uint8List packageBytes;
    try {
      log.message('Publishing from archive: $_fromArchive');

      packageBytes = readBinaryFile(archive);
    } on FileSystemException catch (e) {
      dataError('Failed reading archive file: $e)');
    }
    final Pubspec pubspec;
    try {
      pubspec = Pubspec.parse(
        utf8.decode(
          await extractFileFromTarGz(
            Stream.fromIterable([packageBytes]),
            'pubspec.yaml',
          ),
        ),
        cache.sources,
        containingDescription: ResolvedRootDescription.fromDir(
          p.dirname(archive),
        ),
      );
    } on FormatException catch (e) {
      dataError('Failed to read pubspec.yaml from archive: ${e.message}');
    }
    if (!dryRun && _toArchive == null && pubspec.isPrivate) {
      dataError(
        'A private package cannot be published.\n'
        'You can enable this by changing the "publish_to" field in your '
        'pubspec.',
      );
    }
    final host = computeHost(pubspec);
    log.message('Publishing ${pubspec.name} ${pubspec.version} to $host.');
    return _Publication(
      packageBytes: packageBytes,
      warningCount: 0,
      hintCount: 0,
      pubspec: pubspec,
    );
  }

  /// Validates the package.
  ///
  /// Throws if there are errors and the upload should not proceed.
  ///
  /// Returns a summary of warnings and hints if there are any, otherwise
  /// `null`.
  Future<({int warningsCount, int hintsCount})> _validate(
    Uint8List packageBytes,
    List<String> files,
    Uri host,
  ) async {
    final hints = <String>[];
    final warnings = <String>[];
    final errors = <String>[];

    await log.spinner(
      'Validating package',
      () async => await Validator.runAll(
        entrypoint,
        packageBytes.length,
        host,
        files,
        hints: hints,
        warnings: warnings,
        errors: errors,
      ),
    );

    if (errors.isNotEmpty) {
      dataError(
        'Sorry, your package is missing '
        "${(errors.length > 1) ? 'some requirements' : 'a requirement'} "
        "and can't be published yet.\nFor more information, see: "
        'https://dart.dev/tools/pub/cmd/pub-lish.\n',
      );
    }

    return (warningsCount: warnings.length, hintsCount: hints.length);
  }

  /// Asks the user for confirmation of uploading [package].
  ///
  /// Skips asking if [force].
  /// Throws if user didn't confirm.
  Future<void> _confirmUpload(_Publication package, Uri host) async {
    if (force) return;
    log.message(
      '\nPublishing is forever; packages cannot be unpublished.'
      '\nPolicy details are available at https://pub.dev/policy\n',
    );

    var message =
        'Do you want to publish '
        '${package.pubspec.name} ${package.pubspec.version} to $host';
    if (package.hintCount != 0 || package.warningCount != 0) {
      message = '${package.warningsCountMessage}. $message';
    }
    if (!await confirm('\n$message')) {
      dataError('Package upload canceled.');
    }
  }

  @override
  Future runProtected() async {
    await _validateArgs();
    final publication =
        await (_fromArchive == null
            ? _publicationFromEntrypoint()
            : _publicationFromArchive(_fromArchive));
    if (dryRun) {
      log.message(publication.warningsCountMessage);
      if (publication.warningCount != 0 &&
          !argResults.flag('ignore-warnings')) {
        overrideExitCode(DATA);
      }
      return;
    }
    if (_toArchive == null) {
      final host = computeHost(publication.pubspec);
      await _confirmUpload(publication, host);

      await _publish(publication.packageBytes, host);
    } else {
      if (dryRun) {
        log.message('Would have written to $_toArchive.');
      } else {
        _writeUploadToArchive(publication, _toArchive);
      }
    }
  }

  void _writeUploadToArchive(_Publication publication, String archive) {
    try {
      writeBinaryFile(archive, publication.packageBytes);
    } on FileSystemException catch (e) {
      dataError('Failed writing archive: $e');
    }
    log.message('Wrote package archive at $_toArchive');
  }

  /// Returns the value associated with [key] in [map]. Throws a user-friendly
  /// error if [map] doesn't contain [key].
  dynamic _expectField(Map map, String key, http.Response response) {
    if (map.containsKey(key)) return map[key];
    invalidServerResponse(response);
  }
}

class _Publication {
  Uint8List packageBytes;
  int warningCount;
  int hintCount;

  Pubspec pubspec;

  String get warningsCountMessage {
    final hintText =
        hintCount == 0 ? '' : ' and $hintCount ${pluralize('hint', hintCount)}';
    return '\nPackage has $warningCount '
        '${pluralize('warning', warningCount)}$hintText.';
  }

  _Publication({
    required this.packageBytes,
    required this.warningCount,
    required this.hintCount,
    required this.pubspec,
  });
}
