// 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:yaml/yaml.dart';
import 'package:yaml_edit/yaml_edit.dart';

import '../command.dart';
import '../io.dart';
import '../log.dart' as log;
import '../pubspec.dart';
import '../solver.dart';
import '../utils.dart';

/// Handles the `remove` pub command. Removes dependencies from `pubspec.yaml`,
/// and performs an operation similar to `pub get`. Unlike `pub add`, this
/// command supports the removal of multiple dependencies.
class RemoveCommand extends PubCommand {
  @override
  String get name => 'remove';
  @override
  String get description => '''
Removes dependencies from `pubspec.yaml`.

Invoking `dart pub remove foo bar` will remove `foo` and `bar` from either
`dependencies` or `dev_dependencies` in `pubspec.yaml`.

To remove a dependency override of a package prefix the package name with
'override:'.
''';

  @override
  String get argumentsDescription => '<package1> [<package2>...]';
  @override
  String get docUrl => 'https://dart.dev/tools/pub/cmd/pub-remove';
  @override
  bool get isOffline => argResults.flag('offline');

  bool get isDryRun => argResults.flag('dry-run');

  RemoveCommand() {
    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: 'Precompile executables in immediate dependencies.',
    );

    argParser.addFlag(
      'example',
      defaultsTo: true,
      help: 'Also update dependencies in `example/` (if it exists).',
      hide: true,
    );

    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 removed.');
    }

    final targets = Set<String>.from(argResults.rest).map((descriptor) {
      final isOverride = descriptor.startsWith('override:');
      final name =
          isOverride ? descriptor.substring('override:'.length) : descriptor;
      return _PackageRemoval(name, removeFromOverride: isOverride);
    });

    if (!isDryRun) {
      /// Update the pubspec.
      _writeRemovalToPubspec(targets);
    }
    // TODO(https://github.com/dart-lang/pub/issues/4127): This should
    // operate on entrypoint.workPackage.
    final rootPubspec = entrypoint.workspaceRoot.pubspec;
    final newPubspec = _removePackagesFromPubspec(rootPubspec, targets);

    await entrypoint.withWorkPubspec(newPubspec).acquireDependencies(
          SolveType.get,
          precompile: !isDryRun && argResults.flag('precompile'),
          dryRun: isDryRun,
        );

    var example = entrypoint.example;
    if (!isDryRun && argResults.flag('example') && example != null) {
      await example.acquireDependencies(
        SolveType.get,
        precompile: argResults.flag('precompile'),
        summaryOnly: true,
      );
    }
  }

  Pubspec _removePackagesFromPubspec(
    Pubspec original,
    Iterable<_PackageRemoval> packages,
  ) {
    final dependencies = {...original.dependencies};
    final devDependencies = {...original.devDependencies};
    final overrides = {...original.dependencyOverrides};

    for (final package in packages) {
      if (package.removeFromOverride) {
        overrides.remove(package.name);
      } else {
        dependencies.remove(package.name);
        devDependencies.remove(package.name);
      }
    }
    return Pubspec(
      original.name,
      version: original.version,
      sdkConstraints: original.sdkConstraints,
      dependencies: dependencies.values,
      devDependencies: devDependencies.values,
      dependencyOverrides: overrides.values,
      workspace: original.workspace,
    );
  }

  /// Writes the changes to the pubspec file
  void _writeRemovalToPubspec(Iterable<_PackageRemoval> packages) {
    ArgumentError.checkNotNull(packages, 'packages');

    final yamlEditor =
        YamlEditor(readTextFile(entrypoint.workspaceRoot.pubspecPath));

    for (final package in packages) {
      final dependencyKeys = package.removeFromOverride
          ? ['dependency_overrides']
          : ['dependencies', 'dev_dependencies'];
      var found = false;
      final name = package.name;

      /// There may be packages where the dependency is declared both in
      /// dependencies and dev_dependencies - remove it from both in that case.
      for (final dependencyKey in dependencyKeys) {
        final dependenciesNode = yamlEditor
            .parseAt([dependencyKey], orElse: () => YamlScalar.wrap(null));

        if (dependenciesNode is YamlMap && dependenciesNode.containsKey(name)) {
          yamlEditor.remove([dependencyKey, name]);
          found = true;
          // Check if the dependencies or dev_dependencies map is now empty
          // If it is empty, remove the key as well
          if ((yamlEditor.parseAt([dependencyKey]) as YamlMap).isEmpty) {
            yamlEditor.remove([dependencyKey]);
          }
        }
      }
      if (!found) {
        log.warning(
          'Package "$name" was not found in ${entrypoint.workspaceRoot.pubspecPath}!',
        );
      }
    }

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

class _PackageRemoval {
  final String name;
  final bool removeFromOverride;
  _PackageRemoval(this.name, {required this.removeFromOverride});
}
