// 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:async_helper/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:expect/expect.dart';

void main(List<String> args) {
  ArgParser argParser = new ArgParser(allowTrailingOptions: true);
  argParser.addFlag('continued', abbr: 'c', defaultsTo: false);
  ArgResults argResults = argParser.parse(args);
  Directory dataDir =
      new 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 new 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 = new RegExp("// Error pattern: (.*)\n");
RegExp _kindMatcher = new RegExp("// Kind of minified name: (.*)\n");
RegExp _nameMatcher = new 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 = new 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 = new 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'}:');
  D8Result result = await runWithD8(
      memorySourceFiles: {'main.dart': test.code},
      options: minified ? [Flags.minify, Flags.testMode] : [Flags.testMode]);
  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 new 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 firstStackFrame = stdout.indexOf('\n    at');
  if (firstStackFrame == -1) return null;
  var errorMarker = stdout.indexOf('^') + 1;
  return stdout.substring(errorMarker, firstStackFrame).trim();
}
