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

/// 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);
    }
    final workPubspec = entrypoint.workPackage.pubspec;
    final newPubspec = _removePackagesFromPubspec(workPubspec, targets);

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

    final 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 original.copyWith(
      dependencies: dependencies.values,
      devDependencies: devDependencies.values,
      dependencyOverrides: overrides.values,
    );
  }

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

    final yamlEditor = YamlEditor(
      readTextFile(entrypoint.workPackage.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) {
        final pubspecPath = entrypoint.workPackage.pubspecPath;
        log.warning('Package "$name" was not found in $pubspecPath!');
      }
    }

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

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