// Copyright (c) 2019, 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.

/// Regenerates the static error test markers inside static error tests based
/// on the actual errors reported by analyzer and CFE.
import 'dart:io';

import 'package:args/args.dart';
import 'package:glob/glob.dart';

import 'package:test_runner/src/command_output.dart';
import 'package:test_runner/src/path.dart';
import 'package:test_runner/src/static_error.dart';
import 'package:test_runner/src/test_file.dart';
import 'package:test_runner/src/update_errors.dart';
import 'package:test_runner/src/utils.dart';

const _usage =
    "Usage: dart update_static_error_tests.dart [flags...] <path glob>";

Future<void> main(List<String> args) async {
  var parser = ArgParser();

  parser.addFlag("help", abbr: "h");

  parser.addFlag("dry-run",
      abbr: "n",
      help: "Print result but do not overwrite any files.",
      negatable: false);

  parser.addSeparator("Strip expectations out of the tests:");
  parser.addFlag("remove",
      abbr: "r",
      help: "Remove all existing error expectations.",
      negatable: false);
  parser.addFlag("remove-analyzer",
      help: "Remove existing analyzer error expectations.", negatable: false);
  parser.addFlag("remove-cfe",
      help: "Remove existing CFE error expectations.", negatable: false);

  parser.addSeparator(
      "Insert expectations in the tests based on current front end output:");
  parser.addFlag("insert",
      abbr: "i",
      help: "Insert analyzer and CFE error expectations.",
      negatable: false);
  parser.addFlag("insert-analyzer",
      help: "Insert analyzer error expectations.", negatable: false);
  parser.addFlag("insert-cfe",
      help: "Insert CFE error expectations.", negatable: false);

  parser.addSeparator("Update combines remove and insert:");
  parser.addFlag("update",
      abbr: "u",
      help: "Replace analyzer and CFE error expectations.",
      negatable: false);
  parser.addFlag("update-analyzer",
      help: "Replace analyzer error expectations.", negatable: false);
  parser.addFlag("update-cfe",
      help: "Replace CFE error expectations.", negatable: false);

  var results = parser.parse(args);

  if (results["help"] as bool) {
    print("Regenerates the test markers inside static error tests.");
    print("");
    print(_usage);
    print("");
    print(parser.usage);
    exit(0);
  }

  var dryRun = results["dry-run"] as bool;
  var removeAnalyzer = results["remove-analyzer"] as bool ||
      results["remove"] as bool ||
      results["update-analyzer"] as bool ||
      results["update"] as bool;

  var removeCfe = results["remove-cfe"] as bool ||
      results["remove"] as bool ||
      results["update-cfe"] as bool ||
      results["update"] as bool;

  var insertAnalyzer = results["insert-analyzer"] as bool ||
      results["insert"] as bool ||
      results["update-analyzer"] as bool ||
      results["update"] as bool;

  var insertCfe = results["insert-cfe"] as bool ||
      results["insert"] as bool ||
      results["update-cfe"] as bool ||
      results["update"] as bool;

  if (!removeAnalyzer && !removeCfe && !insertAnalyzer && !insertCfe) {
    _usageError(
        parser, "Must provide at least one flag for an operation to perform.");
  }

  if (results.rest.length != 1) {
    _usageError(
        parser, "Must provide a file path or glob for which tests to update.");
  }

  var result = results.rest.single;
  // Allow tests to be specified without the extension for compatibility with
  // the regular test runner syntax.
  if (!result.endsWith(".dart")) {
    result += ".dart";
  }
  // Allow tests to be specified either relative to the "tests" directory
  // or relative to the current directory.
  var root = result.startsWith("tests") ? "." : "tests";
  var glob = Glob(result, recursive: true);
  for (var entry in glob.listSync(root: root)) {
    if (!entry.path.endsWith(".dart")) continue;

    if (entry is File) {
      await _processFile(entry,
          dryRun: dryRun,
          removeAnalyzer: removeAnalyzer,
          removeCfe: removeCfe,
          insertAnalyzer: insertAnalyzer,
          insertCfe: insertCfe);
    }
  }
}

void _usageError(ArgParser parser, String message) {
  stderr.writeln("Usage error: $message");
  stderr.writeln();
  stderr.writeln(_usage);
  stderr.writeln(parser.usage);
  exit(64);
}

Future<void> _processFile(File file,
    {bool dryRun,
    bool removeAnalyzer,
    bool removeCfe,
    bool insertAnalyzer,
    bool insertCfe}) async {
  stdout.write("${file.path}...");
  var source = file.readAsStringSync();
  var testFile = TestFile.parse(Path("."), file.path, source);

  var errors = <StaticError>[];
  if (insertAnalyzer) {
    stdout.write("\r${file.path} (Running analyzer...)");
    errors.addAll(await _runAnalyzer(file.path, testFile.sharedOptions));
  }

  if (insertCfe) {
    // Clear the previous line.
    stdout.write("\r${file.path}                      ");
    stdout.write("\r${file.path} (Running CFE...)");
    errors.addAll(await _runCfe(file.path, testFile.sharedOptions));
  }

  errors = StaticError.simplify(errors);

  var result = updateErrorExpectations(source, errors,
      removeAnalyzer: removeAnalyzer, removeCfe: removeCfe);

  stdout.writeln("\r${file.path} (Updated with ${errors.length} errors)");

  if (dryRun) {
    print(result);
  } else {
    await file.writeAsString(result);
  }
}

/// Invoke analyzer on [path] and gather all static errors it reports.
Future<List<StaticError>> _runAnalyzer(
    String path, List<String> options) async {
  // TODO(rnystrom): Running the analyzer command line each time is very slow.
  // Either import the analyzer as a library, or at least invoke it in a batch
  // mode.
  var result = await Process.run("sdk/bin/dartanalyzer$shellScriptExtension", [
    ...options,
    "--format=machine",
    path,
  ]);
  var errors = <StaticError>[];
  AnalysisCommandOutput.parseErrors(result.stderr as String, errors);
  return errors;
}

/// Invoke CFE on [path] and gather all static errors it reports.
Future<List<StaticError>> _runCfe(String path, List<String> options) async {
  // TODO(rnystrom): Running the CFE command line each time is slow and wastes
  // time generating code, which we don't care about. Import it as a library or
  // at least run it in batch mode.
  var result = await Process.run("sdk/bin/dart", [
    "pkg/front_end/tool/_fasta/compile.dart",
    ...options,
    "--verify",
    path,
  ]);

  var errors = <StaticError>[];
  FastaCommandOutput.parseErrors(result.stdout as String, errors);

  // Running the above command generates a dill file next to the test, which we
  // don't want, so delete it.
  await File("$path.dill").delete();

  return errors;
}
