// 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 'package:path/path.dart' as p;

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 '../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();
            request.attachMetadataHeaders();
            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();
            request.attachMetadataHeaders();
            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);
  }
}

String _readableFileSize(int size) {
  if (size >= 1 << 30) {
    return '${size ~/ (1 << 30)} GB';
  } else if (size >= 1 << 20) {
    return '${size ~/ (1 << 20)} MB';
  } else if (size >= 1 << 10) {
    return '${size ~/ (1 << 10)} KB';
  } else {
    return '<1 KB';
  }
}

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,
  });
}
