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

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

import 'common.dart';

/// 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-plugin` for full
/// usage information.
///
/// [processRunner], [print], and [stdin] can be overriden for easier testing.
class PublishPluginCommand extends PluginCommand {
  /// Creates an instance of the publish command.
  PublishPluginCommand(
    Directory packagesDir,
    FileSystem fileSystem, {
    ProcessRunner processRunner = const ProcessRunner(),
    Print print = print,
    io.Stdin stdinput,
    GitDir gitDir,
  })  : _print = print,
        _stdin = stdinput ?? io.stdin,
        super(packagesDir, fileSystem,
            processRunner: processRunner, gitDir: gitDir) {
    argParser.addOption(
      _packageOption,
      help: 'The package to publish.'
          'If the package directory name is different than its pubspec.yaml name, then this should specify the directory.',
    );
    argParser.addMultiOption(_pubFlagsOption,
        help:
            'A list of options that will be forwarded on to pub. Separate multiple flags with commas.');
    argParser.addFlag(
      _tagReleaseOption,
      help: 'Whether or not to tag the release.',
      defaultsTo: true,
      negatable: true,
    );
    argParser.addFlag(
      _pushTagsOption,
      help:
          'Whether or not tags should be pushed to a remote after creation. Ignored if tag-release is false.',
      defaultsTo: true,
      negatable: true,
    );
    argParser.addOption(
      _remoteOption,
      help:
          'The name of the remote to push the tags to. Ignored if push-tags or tag-release is false.',
      // 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 plugins that contains pubspec changes at the current commit compares to the base-sha.\n'
          'The $_packageOption option is ignored if this is on.',
      defaultsTo: false,
    );
    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`',
      defaultsTo: false,
      negatable: true,
    );
    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'
            'It also skips the y/n inputs when pushing tags to remote.\n',
        defaultsTo: false,
        negatable: true);
  }

  static const String _packageOption = 'package';
  static const String _tagReleaseOption = 'tag-release';
  static const String _pushTagsOption = 'push-tags';
  static const String _pubFlagsOption = 'pub-publish-flags';
  static const String _remoteOption = 'remote';
  static const String _allChangedFlag = 'all-changed';
  static const String _dryRunFlag = 'dry-run';
  static const String _skipConfirmationFlag = 'skip-confirmation';

  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%';

  @override
  final String name = 'publish-plugin';

  @override
  final String description =
      'Attempts to publish the given plugin and tag its release 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 Print _print;
  final io.Stdin _stdin;
  StreamSubscription<String> _stdinSubscription;

  @override
  Future<void> run() async {
    final String package = argResults[_packageOption] as String;
    final bool publishAllChanged = argResults[_allChangedFlag] as bool;
    if (package == null && !publishAllChanged) {
      _print(
          'Must specify a package to publish. See `plugin_tools help publish-plugin`.');
      throw ToolExit(1);
    }

    _print('Checking local repo...');
    if (!await GitDir.isGitDir(packagesDir.path)) {
      _print('$packagesDir is not a valid Git repository.');
      throw ToolExit(1);
    }
    final GitDir baseGitDir =
        await GitDir.fromExisting(packagesDir.path, allowSubdirectory: true);

    final bool shouldPushTag = argResults[_pushTagsOption] == true;
    final String remote = argResults[_remoteOption] as String;
    String remoteUrl;
    if (shouldPushTag) {
      remoteUrl = await _verifyRemote(remote);
    }
    _print('Local repo is ready!');
    if (argResults[_dryRunFlag] as bool) {
      _print('===============  DRY RUN ===============');
    }

    bool successful;
    if (publishAllChanged) {
      successful = await _publishAllChangedPackages(
        remote: remote,
        remoteUrl: remoteUrl,
        shouldPushTag: shouldPushTag,
        baseGitDir: baseGitDir,
      );
    } else {
      successful = await _publishAndTagPackage(
        packageDir: _getPackageDir(package),
        remote: remote,
        remoteUrl: remoteUrl,
        shouldPushTag: shouldPushTag,
      );
    }
    await _finish(successful);
  }

  Future<bool> _publishAllChangedPackages({
    String remote,
    String remoteUrl,
    bool shouldPushTag,
    GitDir baseGitDir,
  }) async {
    final GitVersionFinder gitVersionFinder = await retrieveVersionFinder();
    final List<String> changedPubspecs =
        await gitVersionFinder.getChangedPubSpecs();
    if (changedPubspecs.isEmpty) {
      _print('No version updates in this commit.');
      return true;
    }
    _print('Getting existing tags...');
    final io.ProcessResult existingTagsResult =
        await baseGitDir.runCommand(<String>['tag', '--sort=-committerdate']);
    final List<String> existingTags = (existingTagsResult.stdout as String)
        .split('\n')
          ..removeWhere((String element) => element.isEmpty);

    final List<String> packagesReleased = <String>[];
    final List<String> packagesFailed = <String>[];

    for (final String pubspecPath in changedPubspecs) {
      final File pubspecFile =
          fileSystem.directory(baseGitDir.path).childFile(pubspecPath);
      final _CheckNeedsReleaseResult result = await _checkNeedsRelease(
        pubspecFile: pubspecFile,
        gitVersionFinder: gitVersionFinder,
        existingTags: existingTags,
      );
      switch (result) {
        case _CheckNeedsReleaseResult.release:
          break;
        case _CheckNeedsReleaseResult.noRelease:
          continue;
        case _CheckNeedsReleaseResult.failure:
          packagesFailed.add(pubspecFile.parent.basename);
          continue;
      }
      _print('\n');
      if (await _publishAndTagPackage(
        packageDir: pubspecFile.parent,
        remote: remote,
        remoteUrl: remoteUrl,
        shouldPushTag: shouldPushTag,
      )) {
        packagesReleased.add(pubspecFile.parent.basename);
      } else {
        packagesFailed.add(pubspecFile.parent.basename);
      }
      _print('\n');
    }
    if (packagesReleased.isNotEmpty) {
      _print('Packages released: ${packagesReleased.join(', ')}');
    }
    if (packagesFailed.isNotEmpty) {
      _print(
          'Failed to release the following packages: ${packagesFailed.join(', ')}, see above for details.');
    }
    return packagesFailed.isEmpty;
  }

  // Publish the package to pub with `pub publish`.
  // If `_tagReleaseOption` is on, git tag the release.
  // If `shouldPushTag` is `true`, the tag will be pushed to `remote`.
  // Returns `true` if publishing and tag are successful.
  Future<bool> _publishAndTagPackage({
    @required Directory packageDir,
    @required String remote,
    @required String remoteUrl,
    @required bool shouldPushTag,
  }) async {
    if (!await _publishPlugin(packageDir: packageDir)) {
      return false;
    }
    if (argResults[_tagReleaseOption] as bool) {
      if (!await _tagRelease(
        packageDir: packageDir,
        remote: remote,
        remoteUrl: remoteUrl,
        shouldPushTag: shouldPushTag,
      )) {
        return false;
      }
    }
    _print('Released [${packageDir.basename}] successfully.');
    return true;
  }

  // Returns a [_CheckNeedsReleaseResult] that indicates the result.
  Future<_CheckNeedsReleaseResult> _checkNeedsRelease({
    @required File pubspecFile,
    @required GitVersionFinder gitVersionFinder,
    @required List<String> existingTags,
  }) async {
    if (!pubspecFile.existsSync()) {
      _print('''
The file at The pubspec file at ${pubspecFile.path} does not exist. Publishing will not happen for ${pubspecFile.parent.basename}.
Safe to ignore if the package is deleted in this commit.
''');
      return _CheckNeedsReleaseResult.noRelease;
    }

    final Pubspec pubspec = Pubspec.parse(pubspecFile.readAsStringSync());
    if (pubspec.publishTo == 'none') {
      return _CheckNeedsReleaseResult.noRelease;
    }

    if (pubspec.version == null) {
      _print(
          'No version found. A package that intentionally has no version should be marked "publish_to: none"');
      return _CheckNeedsReleaseResult.failure;
    }

    if (pubspec.name == null) {
      _print('Fatal: Package name is null.');
      return _CheckNeedsReleaseResult.failure;
    }
    // Get latest tagged version and compare with the current version.
    // TODO(cyanglaz): Check latest version of the package on pub instead of git
    // https://github.com/flutter/flutter/issues/81047

    final String latestTag = existingTags.firstWhere(
        (String tag) => tag.split('-v').first == pubspec.name,
        orElse: () => '');
    if (latestTag.isNotEmpty) {
      final String latestTaggedVersion = latestTag.split('-v').last;
      final Version latestVersion = Version.parse(latestTaggedVersion);
      if (pubspec.version < latestVersion) {
        _print(
            'The new version (${pubspec.version}) is lower than the current version ($latestVersion) for ${pubspec.name}.\nThis git commit is a revert, no release is tagged.');
        return _CheckNeedsReleaseResult.noRelease;
      }
    }
    return _CheckNeedsReleaseResult.release;
  }

  // Publish the plugin.
  //
  // Returns `true` if successful, `false` otherwise.
  Future<bool> _publishPlugin({@required Directory packageDir}) async {
    final bool gitStatusOK = await _checkGitStatus(packageDir);
    if (!gitStatusOK) {
      return false;
    }
    final bool publishOK = await _publish(packageDir);
    if (!publishOK) {
      return false;
    }
    _print('Package published!');
    return true;
  }

  // Tag the release with <plugin-name>-v<version>
  //
  // Return `true` if successful, `false` otherwise.
  Future<bool> _tagRelease({
    @required Directory packageDir,
    @required String remote,
    @required String remoteUrl,
    @required bool shouldPushTag,
  }) async {
    final String tag = _getTag(packageDir);
    _print('Tagging release $tag...');
    if (!(argResults[_dryRunFlag] as bool)) {
      final io.ProcessResult result = await processRunner.run(
        'git',
        <String>['tag', tag],
        workingDir: packageDir,
        exitOnError: false,
        logOnError: true,
      );
      if (result.exitCode != 0) {
        return false;
      }
    }

    if (!shouldPushTag) {
      return true;
    }

    _print('Pushing tag to $remote...');
    return await _pushTagToRemote(
      remote: remote,
      tag: tag,
      remoteUrl: remoteUrl,
    );
  }

  Future<void> _finish(bool successful) async {
    if (_stdinSubscription != null) {
      await _stdinSubscription.cancel();
      _stdinSubscription = null;
    }
    if (successful) {
      _print('Done!');
    } else {
      _print('Failed, see above for details.');
      throw ToolExit(1);
    }
  }

  // Returns the packageDirectory based on the package name.
  // Throws ToolExit if the `package` doesn't exist.
  Directory _getPackageDir(String package) {
    final Directory packageDir = packagesDir.childDirectory(package);
    if (!packageDir.existsSync()) {
      _print('${packageDir.absolute.path} does not exist.');
      throw ToolExit(1);
    }
    return packageDir;
  }

  Future<bool> _checkGitStatus(Directory packageDir) async {
    final io.ProcessResult statusResult = await processRunner.run(
      'git',
      <String>['status', '--porcelain', '--ignored', packageDir.absolute.path],
      workingDir: packageDir,
      logOnError: true,
      exitOnError: false,
    );
    if (statusResult.exitCode != 0) {
      return false;
    }

    final String statusOutput = statusResult.stdout as String;
    if (statusOutput.isNotEmpty) {
      _print(
          "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 remoteInfo = await processRunner.run(
      'git',
      <String>['remote', 'get-url', remote],
      workingDir: packagesDir,
      exitOnError: true,
      logOnError: true,
    );
    return remoteInfo.stdout as String;
  }

  Future<bool> _publish(Directory packageDir) async {
    final List<String> publishFlags =
        argResults[_pubFlagsOption] as List<String>;
    _print(
        'Running `pub publish ${publishFlags.join(' ')}` in ${packageDir.absolute.path}...\n');
    if (argResults[_dryRunFlag] as bool) {
      return true;
    }

    if (argResults[_skipConfirmationFlag] as bool) {
      publishFlags.add('--force');
    }
    if (publishFlags.contains('--force')) {
      _ensureValidPubCredential();
    }

    final io.Process publish = await processRunner.start(
        'flutter', <String>['pub', 'publish'] + publishFlags,
        workingDirectory: packageDir);
    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) {
      _print('Publish ${packageDir.basename} failed.');
      return false;
    }
    return true;
  }

  String _getTag(Directory packageDir) {
    final File pubspecFile =
        fileSystem.file(p.join(packageDir.path, 'pubspec.yaml'));
    final YamlMap pubspecYaml =
        loadYaml(pubspecFile.readAsStringSync()) as YamlMap;
    final String name = pubspecYaml['name'] as String;
    final String 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 remote,
    @required String tag,
    @required String remoteUrl,
  }) async {
    assert(remote != null && tag != null && remoteUrl != null);
    if (!(argResults[_skipConfirmationFlag] as bool)) {
      _print('Ready to push $tag to $remoteUrl (y/n)?');
      final String input = _stdin.readLineSync();
      if (input.toLowerCase() != 'y') {
        _print('Tag push canceled.');
        return false;
      }
    }
    if (!(argResults[_dryRunFlag] as bool)) {
      final io.ProcessResult result = await processRunner.run(
        'git',
        <String>['push', remote, tag],
        workingDir: packagesDir,
        exitOnError: false,
        logOnError: true,
      );
      if (result.exitCode != 0) {
        return false;
      }
    }
    return true;
  }

  void _ensureValidPubCredential() {
    final File credentialFile = fileSystem.file(_credentialsPath);
    if (credentialFile.existsSync() &&
        credentialFile.readAsStringSync().isNotEmpty) {
      return;
    }
    final String credential = io.Platform.environment[_pubCredentialName];
    if (credential == null) {
      printErrorAndExit(errorMessage: '''
No pub credential available. Please check if `~/.pub-cache/credentials.json` is valid.
If running this command on CI, you can set the pub credential content in the $_pubCredentialName environment variable.
''');
    }
    credentialFile.openSync(mode: FileMode.writeOnlyAppend)
      ..writeStringSync(credential)
      ..closeSync();
  }

  /// Returns the correct path where the pub credential is stored.
  @visibleForTesting
  static String getCredentialPath() {
    return _credentialsPath;
  }
}

/// The path in which pub expects to find its credentials file.
final String _credentialsPath = () {
  // This follows the same logic as pub:
  // https://github.com/dart-lang/pub/blob/d99b0d58f4059d7bb4ac4616fd3d54ec00a2b5d4/lib/src/system_cache.dart#L34-L43
  String cacheDir;
  final String pubCache = io.Platform.environment['PUB_CACHE'];
  print(pubCache);
  if (pubCache != null) {
    cacheDir = pubCache;
  } else if (io.Platform.isWindows) {
    final String appData = io.Platform.environment['APPDATA'];
    cacheDir = p.join(appData, 'Pub', 'Cache');
  } else {
    cacheDir = p.join(io.Platform.environment['HOME'], '.pub-cache');
  }
  return p.join(cacheDir, 'credentials.json');
}();

enum _CheckNeedsReleaseResult {
  // The package needs to be released.
  release,

  // The package does not need to be released.
  noRelease,

  // There's an error when trying to determine whether the package needs to be released.
  failure,
}
