// Copyright (c) 2015, 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:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/filenames.dart';
import 'package:compiler/src/io/source_information.dart';
import 'package:compiler/src/js/js_debug.dart';
import 'package:js_ast/js_ast.dart';
import '../helpers/sourcemap_helper.dart';

typedef CodePointWhiteListFunction WhiteListFunction(
    String configuration, String file);

typedef bool CodePointWhiteListFunction(CodePoint codePoint);

CodePointWhiteListFunction emptyWhiteListFunction(String config, String file) {
  return emptyWhiteList;
}

bool emptyWhiteList(CodePoint codePoint) => false;

main(List<String> arguments) {
  test(arguments);
}

void test(List<String> arguments,
    {WhiteListFunction whiteListFunction: emptyWhiteListFunction}) {
  Set<String> configurations = new Set<String>();
  Map<String, Uri> tests = <String, Uri>{};
  if (!parseArguments(arguments, configurations, tests)) {
    return;
  }

  asyncTest(() async {
    bool errorsFound = false;
    for (String file in tests.keys) {
      print('==$file=========================================================');
      for (String config in configurations) {
        List<String> options = TEST_CONFIGURATIONS[config];
        print('---$config----------------------------------------------------');
        Uri uri = tests[file];
        TestResult result = await runTests(config, file, uri, options);
        if (result.missingCodePointsMap.isNotEmpty) {
          errorsFound =
              result.printMissingCodePoints(whiteListFunction(config, file));
        }
        if (result.multipleNodesMap.isNotEmpty) {
          result.printMultipleNodes();
          errorsFound = true;
        }
        if (result.multipleOffsetsMap.isNotEmpty) {
          result.printMultipleOffsets();
          errorsFound = true;
        }
      }
    }
    Expect.isFalse(
        errorsFound,
        "Errors found. "
        "Run the test with a URI option, "
        "`source_mapping_test_viewer [--out=<uri>] [configs] [tests]`, to "
        "create a html visualization of the missing code points.");
  });
}

bool parseArguments(
    List<String> arguments, Set<String> configurations, Map<String, Uri> tests,
    {bool measure: false}) {
  Set<String> extra = arguments.contains('--file') ? new Set<String>() : null;

  for (String argument in arguments) {
    if (!parseArgument(argument, configurations, tests, extra)) {
      return false;
    }
  }

  if (configurations.isEmpty) {
    configurations.addAll(TEST_CONFIGURATIONS.keys);
    if (!measure) {
      configurations.remove('old');
    }
  }
  if (extra != null) {
    for (String file in extra) {
      Uri uri = Uri.base.resolve(nativeToUriPath(file));
      tests[uri.pathSegments.last] = uri;
    }
  }
  if (tests.isEmpty) {
    tests.addAll(TEST_FILES);
  }
  if (arguments.contains('--exclude')) {
    List<String> filesToRemove = new List<String>.from(tests.keys);
    tests.clear();
    tests.addAll(TEST_FILES);
    filesToRemove.forEach(tests.remove);
  }
  return true;
}

/// Parse [argument] for a valid configuration or test-file option.
///
/// On success, the configuration name is added to [configurations] or the
/// test-file name is added to [testFiles], and `true` is returned.
/// On failure, a message is printed and `false` is returned.
///
/// Unmatching arguments are added to [files] is provided.
bool parseArgument(String argument, Set<String> configurations,
    Map<String, Uri> tests, Set<String> extra) {
  if (argument.startsWith('-')) {
    // Skip options.
    return true;
  } else if (TEST_CONFIGURATIONS.containsKey(argument)) {
    configurations.add(argument);
  } else if (TEST_FILES.containsKey(argument)) {
    tests[argument] = TEST_FILES[argument];
  } else if (extra != null) {
    extra.add(argument);
  } else {
    print("Unknown configuration or test file '$argument'. "
        "Must be one of '${TEST_CONFIGURATIONS.keys.join("', '")}' or "
        "'${TEST_FILES.keys.join("', '")}'.");
    return false;
  }
  return true;
}

const Map<String, List<String>> TEST_CONFIGURATIONS = const {
  'ast': const [
    '--use-new-source-info',
    '--use-old-frontend',
  ],
  'kernel': const [],
  'old': const [
    '--use-old-frontend',
  ],
};

final Map<String, Uri> TEST_FILES = _computeTestFiles();

Map<String, Uri> _computeTestFiles() {
  Map<String, Uri> map = <String, Uri>{};
  Directory dataDir = new Directory.fromUri(
      Uri.base.resolve('tests/compiler/dart2js/sourcemaps/data/'));
  for (File file in dataDir.listSync()) {
    Uri uri = file.uri;
    map[uri.pathSegments.last] = uri;
  }
  return map;
}

Future<TestResult> runTests(
    String config, String filename, Uri uri, List<String> options,
    {bool verbose: true}) async {
  SourceMapProcessor processor = new SourceMapProcessor(uri);
  SourceMaps sourceMaps = await processor.process(
      [Flags.useContentSecurityPolicy, Flags.disableInlining]..addAll(options),
      verbose: verbose);
  TestResult result = new TestResult(config, filename, processor);
  for (SourceMapInfo info in sourceMaps.elementSourceMapInfos.values) {
    if (info.element.library.canonicalUri.scheme == 'dart') continue;
    result.userInfoList.add(info);
    Iterable<CodePoint> missingCodePoints =
        info.codePoints.where((c) => c.isMissing);
    if (missingCodePoints.isNotEmpty) {
      result.missingCodePointsMap[info] = missingCodePoints;
    }
    Map<int, Set<SourceLocation>> offsetToLocationsMap =
        <int, Set<SourceLocation>>{};
    for (Node node in info.nodeMap.nodes) {
      info.nodeMap[node]
          .forEach((int targetOffset, List<SourceLocation> sourceLocations) {
        if (sourceLocations.length > 1) {
          Map<Node, List<SourceLocation>> multipleMap = result.multipleNodesMap
              .putIfAbsent(info, () => <Node, List<SourceLocation>>{});
          multipleMap[node] = sourceLocations;
        } else {
          offsetToLocationsMap
              .putIfAbsent(targetOffset, () => new Set<SourceLocation>())
              .addAll(sourceLocations);
        }
      });
    }
    offsetToLocationsMap
        .forEach((int targetOffset, Set<SourceLocation> sourceLocations) {
      if (sourceLocations.length > 1) {
        Map<int, Set<SourceLocation>> multipleMap = result.multipleOffsetsMap
            .putIfAbsent(info, () => <int, Set<SourceLocation>>{});
        multipleMap[targetOffset] = sourceLocations;
      }
    });
  }
  return result;
}

class TestResult {
  final String config;
  final String file;
  final SourceMapProcessor processor;
  List<SourceMapInfo> userInfoList = <SourceMapInfo>[];
  Map<SourceMapInfo, Iterable<CodePoint>> missingCodePointsMap =
      <SourceMapInfo, Iterable<CodePoint>>{};

  /// For each [SourceMapInfo] a map from JS node to multiple source locations
  /// associated with the node.
  Map<SourceMapInfo, Map<Node, List<SourceLocation>>> multipleNodesMap =
      <SourceMapInfo, Map<Node, List<SourceLocation>>>{};

  /// For each [SourceMapInfo] a map from JS offset to multiple source locations
  /// associated with the offset.
  Map<SourceMapInfo, Map<int, Set<SourceLocation>>> multipleOffsetsMap =
      <SourceMapInfo, Map<int, Set<SourceLocation>>>{};

  TestResult(this.config, this.file, this.processor);

  bool printMissingCodePoints(
      [CodePointWhiteListFunction codePointWhiteList = emptyWhiteList]) {
    bool allWhiteListed = true;
    missingCodePointsMap.forEach((info, missingCodePoints) {
      print("Missing code points for ${info.element} in '$file' "
          "in config '$config':");
      for (CodePoint codePoint in missingCodePoints) {
        if (codePointWhiteList(codePoint)) {
          print("  $codePoint (white-listed)");
        } else {
          print("  $codePoint");
          allWhiteListed = false;
        }
      }
    });
    return !allWhiteListed;
  }

  void printMultipleNodes() {
    multipleNodesMap.forEach((info, multipleMap) {
      multipleMap.forEach((node, sourceLocations) {
        print('Multiple source locations:\n ${sourceLocations.join('\n ')}\n'
            'for `${nodeToString(node)}` in ${info.element} in '
            '$file.');
      });
    });
  }

  void printMultipleOffsets() {
    multipleOffsetsMap.forEach((info, multipleMap) {
      multipleMap.forEach((targetOffset, sourceLocations) {
        print('Multiple source locations:\n ${sourceLocations.join('\n ')}\n'
            'for offset $targetOffset in ${info.element} in $file.');
      });
    });
  }
}
