// Copyright 2013 The Flutter Authors
// 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' as io;

import 'package:file/file.dart';
import 'package:git/git.dart';
import 'package:http/http.dart' as http;
import 'package:meta/meta.dart';
import 'package:path/path.dart' as p;
import 'package:platform/platform.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:yaml/yaml.dart';

import 'common/core.dart';
import 'common/file_utils.dart';
import 'common/output_utils.dart';
import 'common/package_command.dart';
import 'common/package_looping_command.dart';
import 'common/pub_utils.dart';
import 'common/pub_version_finder.dart';
import 'common/repository_package.dart';

@immutable
class _RemoteInfo {
  const _RemoteInfo({required this.name, required this.url});

  /// The git name for the remote.
  final String name;

  /// The remote's URL.
  final String url;
}

/// Wraps pub publish with a few niceties used by the flutter/plugin team.
///
/// 1. Checks for any modified files in git and refuses to publish if there's an
///    issue.
/// 2. Tags the release with the format <package-name>-v<package-version>.
/// 3. Pushes the release to a remote.
///
/// Both 2 and 3 are optional, see `plugin_tools help publish` for full
/// usage information.
///
/// [processRunner], [print], and [stdin] can be overriden for easier testing.
class PublishCommand extends PackageLoopingCommand {
  /// Creates an instance of the publish command.
  PublishCommand(
    super.packagesDir, {
    super.processRunner,
    super.platform,
    io.Stdin? stdinput,
    super.gitDir,
    http.Client? httpClient,
  }) : _pubVersionFinder = PubVersionFinder(
         httpClient: httpClient ?? http.Client(),
       ),
       _stdin = stdinput ?? io.stdin {
    argParser.addFlag(
      _alreadyTaggedFlag,
      help:
          'Instead of tagging, validates that the current checkout is already tagged with the expected version.\n'
          'This is primarily intended for use in CI publish steps triggered by tagging.',
      negatable: false,
    );
    argParser.addMultiOption(
      _pubFlagsOption,
      help:
          'A list of options that will be forwarded on to pub. Separate multiple flags with commas.',
    );
    argParser.addOption(
      _remoteOption,
      help: 'The name of the remote to push the tags to.',
      // Flutter convention is to use "upstream" for the single source of truth, and "origin" for personal forks.
      defaultsTo: 'upstream',
    );
    argParser.addFlag(
      _allChangedFlag,
      help:
          'Release all packages that contains pubspec changes at the current commit compares to the base-sha.\n'
          'The --packages option is ignored if this is on.',
    );
    argParser.addOption(
      _batchReleaseBranchOption,
      help: 'batch release a package from its release branch',
    );
    argParser.addFlag(
      _dryRunFlag,
      help:
          'Skips the real `pub publish` and `git tag` commands and assumes both commands are successful.\n'
          'This does not run `pub publish --dry-run`.\n'
          'If you want to run the command with `pub publish --dry-run`, use `pub-publish-flags=--dry-run`',
    );
    argParser.addFlag(
      _skipConfirmationFlag,
      help:
          'Run the command without asking for Y/N inputs.\n'
          'This command will add a `--force` flag to the `pub publish` command if it is not added with $_pubFlagsOption\n',
    );
    argParser.addFlag(
      _tagForAutoPublishFlag,
      help:
          'Runs the dry-run publish, and tags if it succeeds, but does not actually publish.\n'
          'This is intended for use with a separate publish step that is based on tag push events.',
      negatable: false,
    );
  }

  static const String _alreadyTaggedFlag = 'already-tagged';
  static const String _pubFlagsOption = 'pub-publish-flags';
  static const String _remoteOption = 'remote';
  static const String _allChangedFlag = 'all-changed';
  static const String _batchReleaseBranchOption = 'batch-release-branch';
  static const String _dryRunFlag = 'dry-run';
  static const String _skipConfirmationFlag = 'skip-confirmation';
  static const String _tagForAutoPublishFlag = 'tag-for-auto-publish';

  static const String _pubCredentialName = 'PUB_CREDENTIALS';

  // Version tags should follow <package-name>-v<semantic-version>. For example,
  // `flutter_plugin_tools-v0.0.24`.
  static const String _tagFormat = '%PACKAGE%-v%VERSION%';

  /// Returns the correct path where the pub credential is stored.
  @visibleForTesting
  late final String credentialsPath = _getCredentialsPath(
    platform: platform,
    path: path,
  );

  @override
  final String name = 'publish';

  @override
  final String description =
      'Attempts to publish the given packages and tag the release(s) on GitHub.\n'
      'If running this on CI, an environment variable named $_pubCredentialName must be set to a String that represents the pub credential JSON.\n'
      'WARNING: Do not check in the content of pub credential JSON, it should only come from secure sources.';

  final io.Stdin _stdin;
  StreamSubscription<String>? _stdinSubscription;
  final PubVersionFinder _pubVersionFinder;

  // Tags that already exist in the repository.
  List<String> _existingGitTags = <String>[];
  // The remote to push tags to.
  late _RemoteInfo _remote;
  // Flags to pass to `pub publish`.
  late List<String> _publishFlags;

  @override
  String get successSummaryMessage => 'published';

  @override
  String get failureListHeader =>
      'The following packages had failures during publishing:';

  @override
  Future<void> initializeRun() async {
    print('Checking local repo...');

    // Ensure that the requested remote is present.
    final String remoteName = getStringArg(_remoteOption);
    final String? remoteUrl = await _verifyRemote(remoteName);
    if (remoteUrl == null) {
      printError('Unable to find URL for remote $remoteName; cannot push tags');
      throw ToolExit(1);
    }
    _remote = _RemoteInfo(name: remoteName, url: remoteUrl);

    // Pre-fetch all the repository's tags, to check against when publishing.
    final GitDir repository = await gitDir;
    final io.ProcessResult existingTagsResult = await repository.runCommand(
      <String>['tag', '--sort=-committerdate'],
    );
    _existingGitTags = (existingTagsResult.stdout as String).split('\n')
      ..removeWhere((String element) => element.isEmpty);

    _publishFlags = <String>[
      ...getStringListArg(_pubFlagsOption),
      if (getBoolArg(_skipConfirmationFlag)) '--force',
    ];

    if (getBoolArg(_dryRunFlag)) {
      print('=============== DRY RUN ===============');
    }
  }

  @override
  Stream<PackageEnumerationEntry> getPackagesToProcess() async* {
    final String batchReleaseBranchName = getStringArg(
      _batchReleaseBranchOption,
    );
    if (getBoolArg(_allChangedFlag)) {
      print(
        'Publishing all packages that have changed relative to "$baseSha"\n',
      );

      final List<String> changedPubspecs = changedFiles
          .where((String file) => file.trim().endsWith('pubspec.yaml'))
          .toList();

      for (final pubspecPath in changedPubspecs) {
        // Read the ci_config.yaml file if it exists
        final String packageName = p.basename(p.dirname(pubspecPath));
        final bool isBatchReleasePackage;
        try {
          final File ciConfigFile = RepositoryPackage(
            packagesDir.fileSystem.file(pubspecPath).parent,
          ).ciConfigFile;

          if (!ciConfigFile.existsSync()) {
            isBatchReleasePackage = false;
          } else {
            final ciConfig = CIConfig.parse(ciConfigFile.readAsStringSync());
            isBatchReleasePackage = ciConfig.isBatchRelease;
          }
        } catch (e) {
          printError('Could not parse ci_config.yaml for $packageName: $e');
          throw ToolExit(exitCommandFoundErrors);
        }

        // When releasing from the main branch, skip the batch release packages.
        if (batchReleaseBranchName.isEmpty) {
          if (isBatchReleasePackage) {
            continue;
          }
        } else {
          // When releasing from a batch release branch, verify the package has
          // the opt-in flag and that the package name matches the branch suffix.
          // Example: branch "release-go_router" matches package "go_router".
          if (!isBatchReleasePackage ||
              batchReleaseBranchName != 'release-$packageName') {
            continue;
          }
        }

        // git outputs a relativa, Posix-style path.
        final File pubspecFile = childFileWithSubcomponents(
          packagesDir.fileSystem.directory((await gitDir).path),
          p.posix.split(pubspecPath),
        );
        yield PackageEnumerationEntry(
          RepositoryPackage(pubspecFile.parent),
          excluded: false,
        );
      }
    } else {
      yield* getTargetPackages(filterExcluded: false);
    }
  }

  @override
  Future<PackageResult> runForPackage(RepositoryPackage package) async {
    final PackageResult? checkResult = await _checkNeedsRelease(package);
    if (checkResult != null) {
      return checkResult;
    }

    if (!await _runPrePublishScript(package)) {
      return PackageResult.fail(<String>['pre-publish failed']);
    }

    if (!await _checkGitStatus(package)) {
      return PackageResult.fail(<String>['uncommitted changes']);
    }

    final bool tagOnly = getBoolArg(_tagForAutoPublishFlag);
    if (!tagOnly) {
      if (!await _publish(package)) {
        return PackageResult.fail(<String>['publish failed']);
      }
    }

    final String tag = _getTag(package);
    if (getBoolArg(_alreadyTaggedFlag)) {
      if (!(await _getCurrentTags()).contains(tag)) {
        printError('The current checkout is not already tagged "$tag"');
        return PackageResult.fail(<String>['missing tag']);
      }
    } else {
      if (!await _tagRelease(package, tag)) {
        return PackageResult.fail(<String>['tagging failed']);
      }
    }

    final action = tagOnly ? 'Tagged' : 'Published';
    print('\n$action ${package.directory.basename} successfully!');
    return PackageResult.success();
  }

  @override
  Future<void> completeRun() async {
    _pubVersionFinder.httpClient.close();
    await _stdinSubscription?.cancel();
    _stdinSubscription = null;
  }

  /// Checks whether [package] needs to be released, printing check status and
  /// returning one of:
  /// - PackageResult.fail if the check could not be completed
  /// - PackageResult.skip if no release is necessary
  /// - null if releasing should proceed
  ///
  /// In cases where a non-null result is returned, that should be returned
  /// as the final result for the package, without further processing.
  Future<PackageResult?> _checkNeedsRelease(RepositoryPackage package) async {
    if (!package.pubspecFile.existsSync()) {
      logWarning('''
The pubspec file for ${package.displayName} does not exist, so no publishing will happen.
Safe to ignore if the package is deleted in this commit.
''');
      return PackageResult.skip('package deleted');
    }

    final Pubspec pubspec = package.parsePubspec();

    if (pubspec.name == 'flutter_plugin_tools') {
      // Ignore flutter_plugin_tools package when running publishing through flutter_plugin_tools.
      // TODO(cyanglaz): Make the tool also auto publish flutter_plugin_tools package.
      // https://github.com/flutter/flutter/issues/85430
      return PackageResult.skip(
        'publishing flutter_plugin_tools via the tool is not supported',
      );
    }

    if (pubspec.publishTo == 'none') {
      return PackageResult.skip('publish_to: none');
    }

    if (pubspec.version == null) {
      printError(
        'No version found. A package that intentionally has no version should be marked "publish_to: none"',
      );
      return PackageResult.fail(<String>['no version']);
    }

    // Check if the package named `packageName` with `version` has already
    // been published.
    final Version version = pubspec.version!;
    final PubVersionFinderResponse pubVersionFinderResponse =
        await _pubVersionFinder.getPackageVersion(packageName: pubspec.name);
    if (pubVersionFinderResponse.versions.contains(version)) {
      final String tagsForPackageWithSameVersion = _existingGitTags.firstWhere(
        (String tag) =>
            tag.split('-v').first == pubspec.name &&
            tag.split('-v').last == version.toString(),
        orElse: () => '',
      );
      if (tagsForPackageWithSameVersion.isEmpty) {
        printError(
          '${pubspec.name} $version has already been published, however '
          'the git release tag (${pubspec.name}-v$version) was not found. '
          'Please manually fix the tag then run the command again.',
        );
        return PackageResult.fail(<String>['published but untagged']);
      } else {
        print('${pubspec.name} $version has already been published.');
        return PackageResult.skip('already published');
      }
    }
    return null;
  }

  // Tag the release with <package-name>-v<version>, and push it to the remote.
  //
  // Return `true` if successful, `false` otherwise.
  Future<bool> _tagRelease(RepositoryPackage package, String tag) async {
    print('Tagging release $tag...');
    if (!getBoolArg(_dryRunFlag)) {
      final io.ProcessResult result = await (await gitDir).runCommand(<String>[
        'tag',
        tag,
      ], throwOnError: false);
      if (result.exitCode != 0) {
        return false;
      }
    }

    print('Pushing tag to ${_remote.name}...');
    final bool success = await _pushTagToRemote(tag: tag, remote: _remote);
    if (success) {
      print('Release tagged!');
    }
    return success;
  }

  Future<Iterable<String>> _getCurrentTags() async {
    // git tag --points-at HEAD
    final io.ProcessResult tagsResult = await (await gitDir).runCommand(
      <String>['tag', '--points-at', 'HEAD'],
      throwOnError: false,
    );
    if (tagsResult.exitCode != 0) {
      return <String>[];
    }

    return (tagsResult.stdout as String)
        .split('\n')
        .map((String line) => line.trim())
        .where((String line) => line.isNotEmpty);
  }

  Future<bool> _checkGitStatus(RepositoryPackage package) async {
    final io.ProcessResult statusResult = await (await gitDir).runCommand(
      <String>['status', '--porcelain', package.directory.absolute.path],
      throwOnError: false,
    );
    if (statusResult.exitCode != 0) {
      return false;
    }

    final statusOutput = statusResult.stdout as String;
    if (statusOutput.isNotEmpty) {
      printError(
        "There are files in the package directory that haven't been saved in git. Refusing to publish these files:\n\n"
        '$statusOutput\n'
        'If the directory should be clean, you can run `git clean -xdf && git reset --hard HEAD` to wipe all local changes.',
      );
    }
    return statusOutput.isEmpty;
  }

  Future<String?> _verifyRemote(String remote) async {
    final io.ProcessResult getRemoteUrlResult = await (await gitDir).runCommand(
      <String>['remote', 'get-url', remote],
      throwOnError: false,
    );
    if (getRemoteUrlResult.exitCode != 0) {
      return null;
    }
    return getRemoteUrlResult.stdout as String?;
  }

  Future<bool> _runPrePublishScript(RepositoryPackage package) async {
    final File script = package.prePublishScript;
    if (!script.existsSync()) {
      return true;
    }
    final String relativeScriptPath = getRelativePosixPath(
      script,
      from: package.directory,
    );
    print('Running pre-publish hook $relativeScriptPath...');

    // Ensure that dependencies are available.
    if (!await runPubGet(package, processRunner, platform)) {
      printError('Failed to get depenedencies');
      return false;
    }

    final int exitCode = await processRunner.runAndStream('dart', <String>[
      'run',
      relativeScriptPath,
    ], workingDir: package.directory);
    if (exitCode != 0) {
      printError('Pre-publish script failed.');
      return false;
    }
    return true;
  }

  Future<bool> _publish(RepositoryPackage package) async {
    print('Publishing...');
    print(
      'Running `pub publish ${_publishFlags.join(' ')}` in '
      '${package.directory.absolute.path}...\n',
    );
    if (getBoolArg(_dryRunFlag)) {
      return true;
    }

    if (_publishFlags.contains('--force')) {
      _ensureValidPubCredential();
    }

    final io.Process publish = await processRunner.start(
      flutterCommand,
      <String>['pub', 'publish', ..._publishFlags],
      workingDirectory: package.directory,
    );
    publish.stdout.transform(utf8.decoder).listen((String data) => print(data));
    publish.stderr.transform(utf8.decoder).listen((String data) => print(data));
    _stdinSubscription ??= _stdin
        .transform(utf8.decoder)
        .listen((String data) => publish.stdin.writeln(data));
    final int result = await publish.exitCode;
    if (result != 0) {
      printError('Publishing ${package.directory.basename} failed.');
      return false;
    }

    print('Package published!');
    return true;
  }

  String _getTag(RepositoryPackage package) {
    final File pubspecFile = package.pubspecFile;
    final pubspecYaml = loadYaml(pubspecFile.readAsStringSync()) as YamlMap;
    final name = pubspecYaml['name'] as String;
    final version = pubspecYaml['version'] as String;
    // We should have failed to publish if these were unset.
    assert(name.isNotEmpty && version.isNotEmpty);
    return _tagFormat
        .replaceAll('%PACKAGE%', name)
        .replaceAll('%VERSION%', version);
  }

  // Pushes the `tag` to `remote`
  //
  // Return `true` if successful, `false` otherwise.
  Future<bool> _pushTagToRemote({
    required String tag,
    required _RemoteInfo remote,
  }) async {
    if (!getBoolArg(_dryRunFlag)) {
      final io.ProcessResult result = await (await gitDir).runCommand(<String>[
        'push',
        remote.name,
        tag,
      ], throwOnError: false);
      if (result.exitCode != 0) {
        return false;
      }
    }
    return true;
  }

  void _ensureValidPubCredential() {
    final File credentialFile = packagesDir.fileSystem.file(credentialsPath);
    if (credentialFile.existsSync() &&
        credentialFile.readAsStringSync().isNotEmpty) {
      return;
    }
    final String? credential = platform.environment[_pubCredentialName];
    if (credential == null) {
      printError('''
No pub credential available. Please check if `$credentialsPath` is valid.
If running this command on CI, you can set the pub credential content in the $_pubCredentialName environment variable.
''');
      throw ToolExit(1);
    }
    credentialFile.createSync(recursive: true);
    credentialFile.openSync(mode: FileMode.writeOnlyAppend)
      ..writeStringSync(credential)
      ..closeSync();
  }
}

/// The path in which pub expects to find its credentials file.
String _getCredentialsPath({
  required Platform platform,
  required p.Context path,
}) {
  // See https://github.com/dart-lang/pub/blob/master/doc/cache_layout.md#layout
  String? configDir;
  if (platform.isLinux) {
    String? configHome = platform.environment['XDG_CONFIG_HOME'];
    if (configHome == null) {
      final String? home = platform.environment['HOME'];
      if (home == null) {
        printError('"HOME" environment variable is not set.');
      } else {
        configHome = path.join(home, '.config');
      }
    }
    if (configHome != null) {
      configDir = path.join(configHome, 'dart');
    }
  } else if (platform.isWindows) {
    final String? appData = platform.environment['APPDATA'];
    if (appData == null) {
      printError('"APPDATA" environment variable is not set.');
    } else {
      configDir = path.join(appData, 'dart');
    }
  } else if (platform.isMacOS) {
    final String? home = platform.environment['HOME'];
    if (home == null) {
      printError('"HOME" environment variable is not set.');
    } else {
      configDir = path.join(home, 'Library', 'Application Support', 'dart');
    }
  }

  if (configDir == null) {
    printError('Unable to determine pub con location');
    throw ToolExit(1);
  }

  return path.join(configDir, 'pub-credentials.json');
}
