// Copyright (c) 2020, 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 'package:collection/collection.dart' show IterableExtension;
import 'package:path/path.dart' as p;
import 'package:pub_semver/pub_semver.dart';
import 'package:yaml/yaml.dart';
import 'package:yaml_edit/yaml_edit.dart';

import '../command.dart';
import '../entrypoint.dart';
import '../exceptions.dart';
import '../git.dart';
import '../io.dart';
import '../log.dart' as log;
import '../package.dart';
import '../package_name.dart';
import '../pubspec.dart';
import '../solver.dart';
import '../source/path.dart';
import '../utils.dart';

/// Handles the `add` pub command. Adds a dependency to `pubspec.yaml` and gets
/// the package. The user may pass in a git constraint, host url, or path as
/// requirements. If no such options are passed in, this command will do a
/// resolution to find the latest version of the package that is compatible with
/// the other dependencies in `pubspec.yaml`, and then enter that as the lower
/// bound in a ^x.y.z constraint.
///
/// Currently supports only adding one dependency at a time.
class AddCommand extends PubCommand {
  @override
  String get name => 'add';
  @override
  String get description => 'Add a dependency to pubspec.yaml.';
  @override
  String get argumentsDescription => '<package>[:<constraint>] [options]';
  @override
  String get docUrl => 'https://dart.dev/tools/pub/cmd/pub-add';
  @override
  bool get isOffline => argResults['offline'];

  bool get isDev => argResults['dev'];
  bool get isDryRun => argResults['dry-run'];
  String? get gitUrl => argResults['git-url'];
  String? get gitPath => argResults['git-path'];
  String? get gitRef => argResults['git-ref'];
  String? get hostUrl => argResults['hosted-url'];
  String? get path => argResults['path'];
  String? get sdk => argResults['sdk'];

  bool get hasGitOptions => gitUrl != null || gitRef != null || gitPath != null;
  bool get hasHostOptions => hostUrl != null;

  AddCommand() {
    argParser.addFlag('dev',
        abbr: 'd',
        negatable: false,
        help: 'Adds package to the development dependencies instead.');

    argParser.addOption('git-url', help: 'Git URL of the package');
    argParser.addOption('git-ref',
        help: 'Git branch or commit to be retrieved');
    argParser.addOption('git-path', help: 'Path of git package in repository');
    argParser.addOption('hosted-url', help: 'URL of package host server');
    argParser.addOption('path', help: 'Local path');
    argParser.addOption('sdk', help: 'SDK source for package');
    argParser.addFlag(
      'example',
      help:
          'Also update dependencies in `example/` after modifying pubspec.yaml in the root package (if it exists).',
      hide: true,
    );

    argParser.addFlag('offline',
        help: 'Use cached packages instead of accessing the network.');

    argParser.addFlag('dry-run',
        abbr: 'n',
        negatable: false,
        help: "Report what dependencies would change but don't change any.");

    argParser.addFlag('precompile',
        help: 'Build executables in immediate dependencies.');
    argParser.addOption('directory',
        abbr: 'C', help: 'Run this in the directory<dir>.', valueHelp: 'dir');
  }

  @override
  Future<void> runProtected() async {
    if (argResults.rest.isEmpty) {
      usageException('Must specify a package to be added.');
    } else if (argResults.rest.length > 1) {
      usageException('Takes only a single argument.');
    }

    final packageInformation = _parsePackage(argResults.rest.first);
    final package = packageInformation.first;

    /// Perform version resolution in-memory.
    final updatedPubSpec =
        await _addPackageToPubspec(entrypoint.root.pubspec, package);

    late SolveResult solveResult;

    try {
      /// Use [SolveType.UPGRADE] to solve for the highest version of [package]
      /// in case [package] was already a transitive dependency. In the case
      /// where the user specifies a version constraint, this serves to ensure
      /// that a resolution exists before we update pubspec.yaml.
      // TODO(sigurdm): We should really use a spinner here.
      solveResult = await resolveVersions(
          SolveType.upgrade, cache, Package.inMemory(updatedPubSpec));
    } on GitException {
      dataError('Unable to resolve package "${package.name}" with the given '
          'git parameters.');
    } on SolveFailure catch (e) {
      dataError(e.message);
    } on WrappedException catch (e) {
      /// [WrappedException]s may appear if an invalid [hostUrl] is passed in.
      dataError(e.message);
    }

    final resultPackage = solveResult.packages
        .firstWhere((packageId) => packageId.name == package.name);

    /// Assert that [resultPackage] is within the original user's expectations.
    var constraint = package.constraint;
    if (!constraint.allows(resultPackage.version)) {
      var dependencyOverrides = updatedPubSpec.dependencyOverrides;
      if (dependencyOverrides.isNotEmpty) {
        dataError(
            '"${package.name}" resolved to "${resultPackage.version}" which '
            'does not satisfy constraint "${package.constraint}". This could be '
            'caused by "dependency_overrides".');
      }
      dataError(
          '"${package.name}" resolved to "${resultPackage.version}" which '
          'does not satisfy constraint "${package.constraint}".');
    }

    if (isDryRun) {
      /// Even if it is a dry run, run `acquireDependencies` so that the user
      /// gets a report on the other packages that might change version due
      /// to this new dependency.
      final newRoot = Package.inMemory(updatedPubSpec);

      // TODO(jonasfj): Stop abusing Entrypoint.global for dry-run output
      await Entrypoint.global(newRoot, entrypoint.lockFile, cache,
              solveResult: solveResult)
          .acquireDependencies(SolveType.get,
              dryRun: true,
              precompile: argResults['precompile'],
              analytics: analytics);
    } else {
      /// Update the `pubspec.yaml` before calling [acquireDependencies] to
      /// ensure that the modification timestamp on `pubspec.lock` and
      /// `.dart_tool/package_config.json` is newer than `pubspec.yaml`,
      /// ensuring that [entrypoint.assertUptoDate] will pass.
      _updatePubspec(resultPackage, packageInformation, isDev);

      /// Create a new [Entrypoint] since we have to reprocess the updated
      /// pubspec file.
      final updatedEntrypoint = Entrypoint(directory, cache);
      await updatedEntrypoint.acquireDependencies(
        SolveType.get,
        precompile: argResults['precompile'],
        analytics: analytics,
      );

      if (argResults['example'] && entrypoint.example != null) {
        await entrypoint.example!.acquireDependencies(
          SolveType.get,
          precompile: argResults['precompile'],
          onlyReportSuccessOrFailure: true,
          analytics: analytics,
        );
      }
    }

    if (isOffline) {
      log.warning('Warning: Packages added when offline may not resolve to '
          'the latest compatible version available.');
    }
  }

  /// Creates a new in-memory [Pubspec] by adding [package] to the
  /// dependencies of [original].
  Future<Pubspec> _addPackageToPubspec(
      Pubspec original, PackageRange package) async {
    ArgumentError.checkNotNull(original, 'original');
    ArgumentError.checkNotNull(package, 'package');

    final dependencies = [...original.dependencies.values];
    var devDependencies = [...original.devDependencies.values];
    final dependencyNames = dependencies.map((dependency) => dependency.name);
    final devDependencyNames =
        devDependencies.map((devDependency) => devDependency.name);

    if (isDev) {
      /// TODO(walnut): Change the error message once pub upgrade --bump is
      /// released
      if (devDependencyNames.contains(package.name)) {
        dataError('"${package.name}" is already in "dev_dependencies". '
            'Use "pub upgrade ${package.name}" to upgrade to a later version!');
      }

      /// If package is originally in dependencies and we wish to add it to
      /// dev_dependencies, this is a redundant change, and we should not
      /// remove the package from dependencies, since it might cause the user's
      /// code to break.
      if (dependencyNames.contains(package.name)) {
        dataError('"${package.name}" is already in "dependencies". '
            'Use "pub remove ${package.name}" to remove it before adding it '
            'to "dev_dependencies"');
      }

      devDependencies.add(package);
    } else {
      /// TODO(walnut): Change the error message once pub upgrade --bump is
      /// released
      if (dependencyNames.contains(package.name)) {
        dataError('"${package.name}" is already in "dependencies". '
            'Use "pub upgrade ${package.name}" to upgrade to a later version!');
      }

      /// If package is originally in dev_dependencies and we wish to add it to
      /// dependencies, we remove the package from dev_dependencies, since it is
      /// now redundant.
      if (devDependencyNames.contains(package.name)) {
        log.message('"${package.name}" was found in dev_dependencies. '
            'Removing "${package.name}" and adding it to dependencies instead.');
        devDependencies =
            devDependencies.where((d) => d.name != package.name).toList();
      }

      dependencies.add(package);
    }

    return Pubspec(
      original.name,
      version: original.version,
      sdkConstraints: original.sdkConstraints,
      dependencies: dependencies,
      devDependencies: devDependencies,
      dependencyOverrides: original.dependencyOverrides.values,
    );
  }

  /// Parse [package] to return the corresponding [PackageRange], as well as its
  /// representation in `pubspec.yaml`.
  ///
  /// [package] must be written in the format
  /// `<package-name>[:<version-constraint>]`, where quotations should be used
  /// if necessary.
  ///
  /// Examples:
  /// ```
  /// retry
  /// retry:2.0.0
  /// retry:^2.0.0
  /// retry:'>=2.0.0'
  /// retry:'>2.0.0 <3.0.1'
  /// 'retry:>2.0.0 <3.0.1'
  /// retry:any
  /// ```
  ///
  /// If a version constraint is provided when the `--path` or any of the
  /// `--git-<option>` options are used, a [PackageParseError] will be thrown.
  ///
  /// Packages must either be a git, hosted, sdk, or path package. Mixing of
  /// options is not allowed and will cause a [PackageParseError] to be thrown.
  ///
  /// If any of the other git options are defined when `--git-url` is not
  /// defined, an error will be thrown.
  Pair<PackageRange, dynamic> _parsePackage(String package) {
    ArgumentError.checkNotNull(package, 'package');

    final _conflictingFlagSets = [
      ['git-url', 'git-ref', 'git-path'],
      ['hosted-url'],
      ['path'],
      ['sdk'],
    ];

    for (final flag
        in _conflictingFlagSets.expand((s) => s).where(argResults.wasParsed)) {
      final conflictingFlag = _conflictingFlagSets
          .where((s) => !s.contains(flag))
          .expand((s) => s)
          .firstWhereOrNull(argResults.wasParsed);
      if (conflictingFlag != null) {
        usageException(
            'Packages can only have one source, "pub add" flags "--$flag" and '
            '"--$conflictingFlag" are conflicting.');
      }
    }

    /// The package to be added, along with the user-defined package constraints
    /// if present.
    PackageRange packageRange;

    /// The entry to be added to the pubspec. Assigned dynamic because it can
    /// take on either a string for simple version constraints or a map for
    /// more complicated hosted/git options.
    dynamic pubspecInformation;

    final splitPackage = package.split(':');
    final packageName = splitPackage[0];

    /// There shouldn't be more than one `:` in the package information
    if (splitPackage.length > 2) {
      usageException('Invalid package and version constraint: $package');
    }

    /// We want to allow for [constraint] to take on a `null` value here to
    /// preserve the fact that the user did not specify a constraint.
    VersionConstraint? constraint;

    try {
      constraint = splitPackage.length == 2
          ? VersionConstraint.parse(splitPackage[1])
          : null;
    } on FormatException catch (e) {
      usageException('Invalid version constraint: ${e.message}');
    }

    /// Determine the relevant [packageRange] and [pubspecInformation] depending
    /// on the type of package.
    var path = this.path;
    if (hasGitOptions) {
      dynamic git;

      if (gitUrl == null) {
        usageException('The `--git-url` is required for git dependencies.');
      }
      Uri parsed;
      try {
        parsed = Uri.parse(gitUrl!);
      } on FormatException catch (e) {
        usageException('The --git-url must be a valid url: ${e.message}.');
      }
      final urlRelativeToEntrypoint = parsed.isAbsolute
          ? parsed.toString()
          :
          // Turn the relative url from current working directory into a relative
          // url from the entrypoint.
          p.url.relative(
              p.url.join(Uri.file(p.absolute(p.current)).toString(),
                  parsed.toString()),
              from: p.toUri(p.absolute(entrypoint.root.dir)).toString());

      /// Process the git options to return the simplest representation to be
      /// added to the pubspec.
      if (gitRef == null && gitPath == null) {
        git = urlRelativeToEntrypoint;
      } else {
        git = {'url': urlRelativeToEntrypoint, 'ref': gitRef, 'path': gitPath};
        git.removeWhere((key, value) => value == null);
      }

      packageRange = cache.sources.git
          .parseRef(packageName, git, containingPath: entrypoint.pubspecPath)
          .withConstraint(constraint ?? VersionConstraint.any);
      pubspecInformation = {'git': git};
    } else if (path != null) {
      final relativeToEntryPoint = p.isRelative(path)
          ? PathSource.relativePathWithPosixSeparators(
              p.relative(path, from: entrypoint.root.dir))
          : path;
      packageRange = cache.sources.path
          .parseRef(packageName, relativeToEntryPoint,
              containingPath: entrypoint.pubspecPath)
          .withConstraint(constraint ?? VersionConstraint.any);
      pubspecInformation = {'path': relativeToEntryPoint};
    } else if (sdk != null) {
      packageRange = cache.sources.sdk
          .parseRef(packageName, sdk)
          .withConstraint(constraint ?? VersionConstraint.any);
      pubspecInformation = {'sdk': sdk};
    } else {
      final hostInfo =
          hasHostOptions ? {'url': hostUrl, 'name': packageName} : null;

      if (hostInfo == null) {
        pubspecInformation = constraint?.toString();
      } else {
        pubspecInformation = {'hosted': hostInfo};
      }

      packageRange = cache.hosted.source
          .parseRef(
            packageName,
            hostInfo,
            languageVersion: entrypoint.root.pubspec.languageVersion,
          )
          .withConstraint(constraint ?? VersionConstraint.any);
    }

    if (pubspecInformation is Map && constraint != null) {
      /// We cannot simply assign the value of version since it is likely that
      /// [pubspecInformation] takes on the type
      /// [Map<String, Map<String, String>>]
      pubspecInformation = {
        ...pubspecInformation,
        'version': constraint.toString()
      };
    }

    return Pair(packageRange, pubspecInformation);
  }

  /// Writes the changes to the pubspec file.
  void _updatePubspec(PackageId resultPackage,
      Pair<PackageRange, dynamic> packageInformation, bool isDevelopment) {
    ArgumentError.checkNotNull(resultPackage, 'resultPackage');
    ArgumentError.checkNotNull(packageInformation, 'pubspecInformation');

    final package = packageInformation.first;
    var pubspecInformation = packageInformation.last;

    if ((sdk != null || hasHostOptions) &&
        pubspecInformation is Map &&
        pubspecInformation['version'] == null) {
      /// We cannot simply assign the value of version since it is likely that
      /// [pubspecInformation] takes on the type
      /// [Map<String, Map<String, String>>]
      pubspecInformation = {
        ...pubspecInformation,
        'version': '^${resultPackage.version}'
      };
    }

    final dependencyKey = isDevelopment ? 'dev_dependencies' : 'dependencies';
    final packagePath = [dependencyKey, package.name];

    final yamlEditor = YamlEditor(readTextFile(entrypoint.pubspecPath));
    log.io('Reading ${entrypoint.pubspecPath}.');
    log.fine('Contents:\n$yamlEditor');

    /// Handle situations where the user might not have the dependencies or
    /// dev_dependencies map.
    if (yamlEditor.parseAt([dependencyKey],
            orElse: () => YamlScalar.wrap(null)).value ==
        null) {
      yamlEditor.update([dependencyKey],
          {package.name: pubspecInformation ?? '^${resultPackage.version}'});
    } else {
      yamlEditor.update(
          packagePath, pubspecInformation ?? '^${resultPackage.version}');
    }

    log.fine('Added ${package.name} to "$dependencyKey".');

    /// Remove the package from dev_dependencies if we are adding it to
    /// dependencies. Refer to [_addPackageToPubspec] for additional discussion.
    if (!isDevelopment) {
      final devDependenciesNode = yamlEditor
          .parseAt(['dev_dependencies'], orElse: () => YamlScalar.wrap(null));

      if (devDependenciesNode is YamlMap &&
          devDependenciesNode.containsKey(package.name)) {
        if (devDependenciesNode.length == 1) {
          yamlEditor.remove(['dev_dependencies']);
        } else {
          yamlEditor.remove(['dev_dependencies', package.name]);
        }

        log.fine('Removed ${package.name} from "dev_dependencies".');
      }
    }

    /// Windows line endings are already handled by [yamlEditor]
    writeTextFile(entrypoint.pubspecPath, yamlEditor.toString());
  }
}
