// 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 'dart:convert';

import 'package:args/args.dart';
import 'package:expect/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:dart2js_tools/src/dart2js_mapping.dart';

import '../helpers/d8_helper.dart';
import 'package:compiler/src/util/memory_compiler.dart';
import 'package:expect/expect.dart';

void main(List<String> args) {
  ArgParser argParser = ArgParser(allowTrailingOptions: true);
  argParser.addFlag('continued', abbr: 'c', defaultsTo: false);
  ArgResults argResults = argParser.parse(args);
  Directory dataDir = Directory.fromUri(Platform.script.resolve('minified'));
  print('Input folder: ${dataDir.uri}');
  asyncTest(() async {
    bool continuing = false;
    await for (FileSystemEntity entity in dataDir.list()) {
      String name = entity.uri.pathSegments.last;
      if (!name.endsWith('.dart')) continue;
      if (argResults.rest.isNotEmpty &&
          !argResults.rest.contains(name) &&
          !continuing) {
        continue;
      }
      print('\ninput $name');
      await runTest(await File.fromUri(entity.uri).readAsString());
      if (argResults['continued']) continuing = true;
    }
  });
}

// Object to hold the expectations of a individual minified-name test.
class MinifiedNameTest {
  /// Pattern used to find a minified name in the error message.
  final RegExp pattern;

  /// The kind of minified name, it can be global, instance, or other
  /// (the first two correspond to the two namespaces that contain extra data in
  /// the source-map file).
  final String _kind;

  /// Whether the minified name is from the global namespace.
  bool get isGlobal => _kind == 'global';

  /// Whether the minified name is from the instance namespace.
  bool get isInstance => _kind == 'instance';

  /// The deobfuscated name we expect to find.
  final String expectedName;

  /// The actual test code.
  final String code;

  MinifiedNameTest(this.pattern, this._kind, this.expectedName, this.code);
}

RegExp _patternMatcher = RegExp("// Error pattern: (.*)\n");
RegExp _kindMatcher = RegExp("// Kind of minified name: (.*)\n");
RegExp _nameMatcher = RegExp("// Expected deobfuscated name: (.*)\n");

Future runTest(String code) async {
  var patternMatch = _patternMatcher.firstMatch(code);
  Expect.isNotNull(patternMatch, "Could not find the error pattern.");
  var pattern = RegExp(patternMatch!.group(1)!);
  var kindMatch = _kindMatcher.firstMatch(code);
  Expect.isNotNull(kindMatch, "Could not find the expected minified kind.");
  var kind = kindMatch!.group(1)!;

  // TODO(sigmund): add support for "other" when we encode symbol information
  // directly for each field and local variable.
  const validKinds = const ['global', 'instance'];
  Expect.isTrue(
    validKinds.contains(kind),
    "Invalid kind: $kind, please use one of $validKinds",
  );

  var nameMatch = _nameMatcher.firstMatch(code);
  Expect.isNotNull(nameMatch, "Could not find the expected deobfuscated name.");
  var expectedName = nameMatch!.group(1)!;
  var test = MinifiedNameTest(pattern, kind, expectedName, code);
  print('expectations: ${pattern.pattern} $kind $expectedName');
  await checkExpectation(test, false);
  await checkExpectation(test, true);
}

checkExpectation(MinifiedNameTest test, bool minified) async {
  print('-- ${minified ? 'minified' : 'not-minified'}:');
  var options = [
    Flags.testMode,
    '--libraries-spec=$sdkLibrariesSpecificationUri',
    if (minified) Flags.minify,
  ];
  D8Result result = await runWithD8(
    memorySourceFiles: {'main.dart': test.code},
    options: options,
  );
  String stdout = result.runResult.stdout;
  String? error = _extractError(stdout);
  print('   error: $error');
  Expect.isNotNull(error, 'Couldn\'t find the error message in $stdout');

  var match = test.pattern.firstMatch(error!);
  Expect.isNotNull(
    match,
    'Error didn\'t match the test pattern'
    '\nerror: $error\npattern:${test.pattern}',
  );
  var name = match!.group(1)!;
  print('   obfuscated-name: $name');
  Expect.isNotNull(name, 'Error didn\'t contain a name\nerror: $error');

  if (name.startsWith('minified:')) {
    name = name.substring(9);
  }

  var sourceMap = '${result.outputPath}.map';
  var json = jsonDecode(await File(sourceMap).readAsString());

  var mapping = Dart2jsMapping.json(json);
  Expect.isTrue(
    mapping.globalNames.isNotEmpty,
    "Source-map doesn't contain minified-names",
  );

  var actualName;
  if (test.isGlobal) {
    actualName = mapping.globalNames[name];
    Expect.isNotNull(actualName, "'$name' not in global name map");
  } else if (test.isInstance) {
    // In non-minified mode some errors show the original name
    // rather than the selector name (e.g. m1 instead of m1$0 in a
    // NoSuchMethodError), and because of that the name might not be on the
    // table.
    //
    // TODO(sigmund): consider making all errors show the internal name, or
    // include a marker to make it easier to distinguish.
    actualName = mapping.instanceNames[name] ?? name;
  } else {
    Expect.fail('unexpected');
  }
  print('   actual-name: $actualName');
  Expect.equals(test.expectedName, actualName);
  print('   PASS!!');
}

/// Returns the portion of the output that corresponds to the error message.
///
/// Note: some errors can span multiple lines.
String? _extractError(String stdout) {
  var start = stdout.indexOf(': ');
  if (start == -1) return null;
  var end = stdout.indexOf('throw e;');
  return stdout.substring(start + 2, end).trim();
}
