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

import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:build_runner_core/build_runner_core.dart';
import 'package:build_runner_core/src/asset_graph/graph.dart';
import 'package:build_runner_core/src/asset_graph/node.dart';
import 'package:logging/logging.dart';

import '../logging/std_io_logging.dart';
import 'base_command.dart';

class CleanCommand extends Command<int> {
  @override
  final argParser = ArgParser(usageLineLength: lineLength);

  @override
  String get name => 'clean';

  @override
  String get description =>
      'Cleans up output from previous builds. Does not clean up --output '
      'directories.';

  Logger get logger => Logger(name);

  @override
  Future<int> run() async {
    var logSubscription = Logger.root.onRecord.listen(stdIOLogListener());
    await cleanFor(assetGraphPath, logger);
    await logSubscription.cancel();
    return 0;
  }
}

Future<void> cleanFor(String assetGraphPath, Logger logger) async {
  logger.warning('Deleting cache and generated source files.\n'
      'This shouldn\'t be necessary for most applications, unless you have '
      'made intentional edits to generated files (i.e. for testing). '
      'Consider filing a bug at '
      'https://github.com/dart-lang/build/issues/new if you are using this '
      'to work around an apparent (and reproducible) bug.');

  await logTimedAsync(logger, 'Cleaning up source outputs', () async {
    var assetGraphFile = File(assetGraphPath);
    if (!assetGraphFile.existsSync()) {
      logger.warning('No asset graph found. '
          'Skipping cleanup of generated files in source directories.');
      return;
    }
    AssetGraph assetGraph;
    try {
      assetGraph = AssetGraph.deserialize(await assetGraphFile.readAsBytes());
    } catch (_) {
      logger.warning('Failed to deserialize AssetGraph. '
          'Skipping cleanup of generated files in source directories.');
      return;
    }
    var packageGraph = PackageGraph.forThisPackage();
    await _cleanUpSourceOutputs(assetGraph, packageGraph);
  });

  await logTimedAsync(
      logger, 'Cleaning up cache directory', _cleanUpGeneratedDirectory);
}

Future<void> _cleanUpSourceOutputs(
    AssetGraph assetGraph, PackageGraph packageGraph) async {
  var writer = FileBasedAssetWriter(packageGraph);
  for (var id in assetGraph.outputs) {
    if (id.package != packageGraph.root.name) continue;
    var node = assetGraph.get(id) as GeneratedAssetNode;
    if (node.wasOutput) {
      // Note that this does a file.exists check in the root package and
      // only tries to delete the file if it exists. This way we only
      // actually delete to_source outputs, without reading in the build
      // actions.
      await writer.delete(id);
    }
  }
}

Future<void> _cleanUpGeneratedDirectory() async {
  var generatedDir = Directory(cacheDir);
  if (await generatedDir.exists()) {
    await generatedDir.delete(recursive: true);
  }
}
