// Copyright (c) 2025, 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 'dart:convert';
import 'dart:io';

import '../command.dart';
import '../command_runner.dart';
import '../io.dart';
import '../log.dart' as log;
import '../package_config.dart';
import '../path.dart';
import '../utils.dart';

class CacheGcCommand extends PubCommand {
  @override
  String get name => 'gc';
  @override
  String get description => 'Prunes unused packages from the system cache.';
  @override
  bool get takesArguments => false;

  final dontRemoveFilesOlderThan = const Duration(hours: 2);

  CacheGcCommand() {
    argParser.addFlag(
      'force',
      abbr: 'f',
      help: 'Prune cache without confirmation',
      hideNegatedUsage: true,
    );
    argParser.addFlag(
      'collect-recent',
      help: 'Also delete recent files',
      hideNegatedUsage: true,
    );
    argParser.addFlag(
      'dry-run',
      help: 'Print list of files that would be deleted',
      hideNegatedUsage: true,
    );
  }

  @override
  Future<void> runProtected() async {
    final dryRun = argResults.flag('dry-run');
    final activeRoots = cache.activeRoots();
    // All the `activeRoots` that we could read and parse a
    // .dart_tool/packageConfig.json from.
    final validActiveRoots = <String>[];
    // All the rootUri paths to cached packages included from
    // `validActiveRoots`.
    final paths = <String>{};
    for (final packageConfigPath in activeRoots) {
      late final PackageConfig packageConfig;
      try {
        packageConfig = PackageConfig.fromJson(
          json.decode(readTextFile(packageConfigPath)),
        );
      } on IOException catch (e) {
        // Failed to read file - probably got deleted.
        log.fine('Failed to read packageConfig $packageConfigPath: $e');
        continue;
      } on FormatException catch (e) {
        log.warning(
          'Failed to decode packageConfig $packageConfigPath: $e.\n'
          'It could be corrupted',
        );
        // Failed to decode - probably corrupted.
        continue;
      }
      for (final package in packageConfig.packages) {
        final rootUri = p.canonicalize(
          package.resolvedRootDir(packageConfigPath),
        );
        if (p.isWithin(cache.rootDir, rootUri)) {
          paths.add(rootUri);
        }
      }
      validActiveRoots.add(packageConfigPath);
    }
    final now = DateTime.now();
    final allPathsToGC =
        [
          for (final source in cache.cachedSources)
            ...await source.entriesToGc(
              cache,
              paths
                  .where(
                    (path) => p.isWithin(
                      p.canonicalize(cache.rootDirForSource(source)),
                      path,
                    ),
                  )
                  .toSet(),
            ),
        ].where((path) {
          // Only clear cache entries older than 2 hours to avoid race
          // conditions with ongoing `pub get` processes.
          final s = statPath(path);
          if (s.type == FileSystemEntityType.notFound) return false;
          if (argResults.flag('collect-recent')) return true;
          return now.difference(s.modified) > dontRemoveFilesOlderThan;
        }).toList();
    if (validActiveRoots.isEmpty) {
      log.message('Found no active projects.');
    } else {
      final s = validActiveRoots.length == 1 ? '' : 's';
      log.message('Found ${validActiveRoots.length} active project$s:');
      for (final packageConfigPath in validActiveRoots) {
        final parts = p.split(packageConfigPath);
        var projectDir = packageConfigPath;
        if (parts[parts.length - 2] == '.dart_tool' &&
            parts[parts.length - 1] == 'package_config.json') {
          projectDir = p.joinAll(parts.sublist(0, parts.length - 2));
        }
        log.message('* $projectDir');
      }
    }
    var sum = 0;
    for (final entry in allPathsToGC) {
      if (dirExists(entry)) {
        for (final file in listDir(
          entry,
          recursive: true,
          includeHidden: true,
          includeDirs: false,
        )) {
          sum += tryStatFile(file)?.size ?? 0;
        }
      } else {
        sum += tryStatFile(entry)?.size ?? 0;
      }
    }
    if (sum == 0) {
      log.message('No unused cache entries found.');
      return;
    }
    log.message('');
    log.message(
      '''
All other projects ${dryRun ? 'would' : 'will'} need to run `$topLevelProgram pub get` again to work correctly.''',
    );
    log.message(
      '${dryRun ? 'Would' : 'Will'} recover ${readableFileSize(sum)}.',
    );
    if (dryRun) {
      log.message('Would delete:');
      for (final path in allPathsToGC..sort()) {
        log.message(path);
      }
    } else if (argResults.flag('force') ||
        await confirm('Are you sure you want to continue?')) {
      await log.progress('Deleting unused cache entries', () async {
        for (final path in allPathsToGC..sort()) {
          tryDeleteEntry(path);
        }
      });
    }
  }
}
