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

/// Tests code generation.
///
/// Runs Dart Dev Compiler on all input in the `codegen` directory and checks
/// that the output is what we expected.
library dev_compiler.test.codegen_test;

// TODO(rnystrom): This doesn't actually run any tests any more. It just
// compiles stuff. This should be changed to not use unittest and just be a
// regular program that outputs files.

import 'dart:convert';
import 'dart:io' show Directory, File, Platform;
import 'package:analyzer/analyzer.dart' show StringLiteral, parseDirectives;
import 'package:analyzer/src/command_line/arguments.dart'
    show defineAnalysisArguments;
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/generated/source.dart' show Source;
import 'package:args/args.dart' show ArgParser, ArgResults;
import 'package:dev_compiler/src/analyzer/context.dart';
import 'package:dev_compiler/src/analyzer/module_compiler.dart'
    show BuildUnit, CompilerOptions, JSModuleFile, ModuleCompiler;
import 'package:dev_compiler/src/compiler/module_builder.dart'
    show ModuleFormat, addModuleFormatOptions, parseModuleFormatOption;
import 'package:path/path.dart' as path;
import 'package:test/test.dart' show expect, isFalse, isTrue, test;
import 'package:status_file/expectation.dart';
import 'package:test_dart/path.dart' as test_dart;
import 'package:test_dart/test_suite.dart' show StandardTestSuite;
import 'package:test_dart/options.dart';

import '../tool/build_sdk.dart' as build_sdk;
import 'multitest.dart' show extractTestsFromMultitest, isMultiTest;
import 'testing.dart' show repoDirectory, testDirectory;

final ArgParser argParser = new ArgParser()
  ..addOption('dart-sdk', help: 'Dart SDK Path', defaultsTo: null);

/// The `test/codegen` directory.
final codegenDir = path.join(testDirectory, 'codegen');

/// The `test/codegen/expect` directory.
final codegenExpectDir = path.join(testDirectory, 'codegen_expected');

/// The generated directory where tests, expanded multitests, and other test
/// support libraries are copied to.
///
/// The tests sometimes import utility libraries using a relative path.
/// Likewise, the multitests do too, and one multitest even imports its own
/// non-expanded form (!). To make that simpler, we copy the entire test tree
/// to a generated directory and expand that multitests in there too.
final codegenTestDir = path.join(repoDirectory, 'gen', 'codegen_tests');

/// The generated directory where tests and packages compiled to JS are
/// output.
final codegenOutputDir = path.join(repoDirectory, 'gen', 'codegen_output');

final codeCoverage = Platform.environment.containsKey('COVERALLS_TOKEN');

RegExp filePattern;

main(List<String> arguments) {
  if (arguments == null) arguments = [];
  ArgResults args = argParser.parse(arguments);
  filePattern = new RegExp(args.rest.length > 0 ? args.rest[0] : '.');

  var sdkDir = path.join(repoDirectory, 'gen', 'patched_sdk');
  var sdkSummaryFile =
      path.join(testDirectory, '..', 'gen', 'sdk', 'ddc_sdk.sum');

  var summaryPaths = new Directory(path.join(codegenOutputDir, 'pkg'))
      .listSync()
      .map((e) => e.path)
      .where((p) => p.endsWith('.sum'))
      .toList();

  var sharedCompiler = new ModuleCompiler(new AnalyzerOptions.basic(
      dartSdkSummaryPath: sdkSummaryFile, summaryPaths: summaryPaths));

  var testDirs = ['language', 'corelib_2', 'lib'];

  // Copy all of the test files and expanded multitest files to
  // gen/codegen_tests. We'll compile from there.
  var testFiles = _setUpTests(testDirs);
  _writeRuntimeStatus(testFiles);

  // Our default compiler options. Individual tests can override these.
  var defaultOptions = ['--no-source-map', '--no-summarize'];
  var compileArgParser = new ArgParser();
  defineAnalysisArguments(compileArgParser, ddc: true);
  AnalyzerOptions.addArguments(compileArgParser);
  CompilerOptions.addArguments(compileArgParser);
  addModuleFormatOptions(compileArgParser);

  var testFileOptionsMatcher =
      new RegExp(r'// (compile options: |SharedOptions=)(.*)', multiLine: true);

  // Ignore dart2js options that we don't support in DDC.
  var ignoreOptions = [
    '--enable-enum',
    '--experimental-trust-js-interop-type-annotations',
    '--trust-type-annotations',
    '--supermixin'
  ];

  // Compile each test file to JS and put the result in gen/codegen_output.
  testFiles.forEach((testFile, status) {
    var relativePath = path.relative(testFile, from: codegenTestDir);

    // Only compile the top-level files for generating coverage.
    bool isTopLevelTest = path.dirname(relativePath) == ".";
    if (codeCoverage && !isTopLevelTest) return;

    if (status.contains(Expectation.skip) ||
        status.contains(Expectation.skipByDesign)) {
      return;
    }

    var name = path.withoutExtension(relativePath);
    test('dartdevc $name', () {
      // Check if we need to use special compile options.
      var contents = new File(testFile).readAsStringSync();
      var match = testFileOptionsMatcher.firstMatch(contents);

      var args = defaultOptions.toList();
      if (match != null) {
        var matchedArgs = match.group(2).split(' ');
        args.addAll(matchedArgs.where((s) => !ignoreOptions.contains(s)));
      }

      ArgResults argResults = compileArgParser.parse(args);
      var analyzerOptions = new AnalyzerOptions.fromArguments(argResults,
          dartSdkSummaryPath: sdkSummaryFile, summaryPaths: summaryPaths);

      var options = new CompilerOptions.fromArguments(argResults);

      var moduleFormat = parseModuleFormatOption(argResults).first;

      // Collect any other files we've imported.
      var files = new Set<String>();
      _collectTransitiveImports(contents, files, from: testFile);
      var unit = new BuildUnit(
          name, path.dirname(testFile), files.toList(), _moduleForLibrary);

      var compiler = sharedCompiler;
      if (analyzerOptions.declaredVariables.isNotEmpty) {
        compiler = new ModuleCompiler(analyzerOptions);
      }
      JSModuleFile module = null;
      var exception, stackTrace;
      try {
        module = compiler.compile(unit, options);
      } catch (e, st) {
        exception = e;
        stackTrace = st;
      }

      // This covers tests where the intent of the test is to validate that
      // some static error is produced.
      var intentionalCompileError =
          (contents.contains(': compile-time error') ||
                  // Use adjacent strings so test.dart doesn't match this line
                  // as an expected compile error.
                  contents.contains('/*@' 'compile-error=')) &&
              !status.contains(Expectation.missingCompileTimeError);

      var crashing = status.contains(Expectation.crash);
      if (module == null) {
        expect(crashing, isTrue,
            reason: "test $name crashes during compilation.\n"
                "$exception\n$stackTrace");
        return;
      }

      // Write out JavaScript and/or compilation errors/warnings.
      _writeModule(
          path.join(codegenOutputDir, name),
          isTopLevelTest ? path.join(codegenExpectDir, name) : null,
          moduleFormat,
          module);

      expect(crashing, isFalse, reason: "test $name no longer crashes.");

      var knownCompileError = status.contains(Expectation.compileTimeError) ||
          status.contains(Expectation.fail);
      // TODO(jmesserly): we could also invert negative_test, however analyzer
      // in test.dart does not do this.
      //   name.endsWith('negative_test') && !status.contains(Expectation.fail)
      if (module.isValid) {
        expect(knownCompileError, isFalse,
            reason: "test $name expected static errors, but compiled.");
      } else {
        var reason = intentionalCompileError ? "intended" : "unexpected";
        expect(intentionalCompileError || knownCompileError, isTrue,
            reason: "test $name failed to compile due to $reason errors:"
                "\n\n${module.errors.join('\n')}.");
      }
    });
  });

  if (filePattern.hasMatch('sunflower')) {
    test('sunflower', () {
      _buildSunflower(sharedCompiler, codegenOutputDir, codegenExpectDir);
    });
  }

  if (codeCoverage) {
    test('build_sdk code coverage', () {
      return build_sdk.main(['--dart-sdk', sdkDir, '-o', codegenOutputDir]);
    });
  }
}

void _writeModule(String outPath, String expectPath, ModuleFormat format,
    JSModuleFile result) {
  _ensureDirectory(path.dirname(outPath));

  String errors = result.errors.join('\n');
  if (errors.isNotEmpty && !errors.endsWith('\n')) errors += '\n';
  new File(outPath + '.txt').writeAsStringSync(errors);

  if (result.isValid) {
    result.writeCodeSync(format, outPath + '.js');
  }

  if (result.summaryBytes != null) {
    new File(outPath + '.sum').writeAsBytesSync(result.summaryBytes);
  }

  // Write the expectation file if needed.
  // Generally speaking we try to avoid these tests, but they are occasionally
  // useful.
  if (expectPath != null) {
    _ensureDirectory(path.dirname(expectPath));

    var expectFile = new File(expectPath + '.js');
    if (result.isValid) {
      result.writeCodeSync(format, expectFile.path);
    } else {
      expectFile.writeAsStringSync("//FAILED TO COMPILE");
    }
  }
}

void _buildSunflower(
    ModuleCompiler compiler, String outputDir, String expectDir) {
  var baseDir = path.join(codegenDir, 'sunflower');
  var files = ['sunflower', 'circle', 'painter']
      .map((f) => path.join(baseDir, '$f.dart'))
      .toList();
  var input = new BuildUnit('sunflower', baseDir, files, _moduleForLibrary);
  var options = new CompilerOptions(summarizeApi: false);

  var built = compiler.compile(input, options);
  _writeModule(path.join(outputDir, 'sunflower', 'sunflower'),
      path.join(expectDir, 'sunflower', 'sunflower'), ModuleFormat.amd, built);
}

String _moduleForLibrary(Source source) {
  var scheme = source.uri.scheme;
  if (scheme == 'package') {
    return source.uri.pathSegments.first;
  }
  throw new Exception('Module not found for library "${source.fullName}"');
}

void _writeRuntimeStatus(Map<String, Set<Expectation>> testFiles) {
  var runtimeStatus = <String, String>{};
  testFiles.forEach((name, status) {
    name = path.withoutExtension(path.relative(name, from: codegenTestDir));
    // Skip tests that we don't expect to compile.
    if (status.contains(Expectation.compileTimeError) ||
        status.contains(Expectation.crash) ||
        status.contains(Expectation.skip) ||
        status.contains(Expectation.fail) ||
        status.contains(Expectation.skipByDesign)) {
      return;
    }
    // Normalize the expectations for the Karma language_test.js runner.
    if (status.remove(Expectation.ok)) assert(status.isNotEmpty);
    if (status.remove(Expectation.missingCompileTimeError) ||
        status.remove(Expectation.missingRuntimeError)) {
      status.add(Expectation.pass);
    }

    // Don't include status for passing tests, as that is the default.
    // TODO(jmesserly): we could record these for extra sanity checks.
    if (status.length == 1 && status.contains(Expectation.pass)) {
      return;
    }

    runtimeStatus[name] = status.map((s) => '$s').join(',');
  });
  new File(path.join(codegenOutputDir, 'test_status.js')).writeAsStringSync('''
define([], function() {
  'use strict';
  return ${new JsonEncoder.withIndent(' ').convert(runtimeStatus)};
});
''');
}

Map<String, Set<Expectation>> _setUpTests(List<String> testDirs) {
  var testFiles = <String, Set<Expectation>>{};
  for (var testDir in testDirs) {
    // TODO(rnystrom): Simplify this when the Dart 2.0 test migration is
    // complete (#30183).
    // Look for the tests in the "_strong" and "_2" directories in the SDK's
    // main "tests" directory.
    var dirParts = path.split(testDir);

    for (var suffix in const ["_2", "_strong"]) {
      var sdkTestDir = path.join(
          'tests', dirParts[0] + suffix, path.joinAll(dirParts.skip(1)));
      var inputPath = path.join(testDirectory, '..', '..', '..', sdkTestDir);

      if (!new Directory(inputPath).existsSync()) continue;

      var browsers = Platform.environment['DDC_BROWSERS'];
      var runtime = browsers == 'Firefox' ? 'firefox' : 'chrome';
      var config = new OptionsParser()
          .parse('-m release -c dartdevc --use-sdk --strong'.split(' ')
            ..addAll(['-r', runtime, '--suite_dir', sdkTestDir]))
          .single;

      var testSuite = new StandardTestSuite.forDirectory(
          config, new test_dart.Path(sdkTestDir));
      var expectations = testSuite.readExpectations();

      for (var file in _listFiles(inputPath, recursive: true)) {
        var relativePath = path.relative(file, from: inputPath);
        var outputPath = path.join(codegenTestDir, testDir, relativePath);

        _ensureDirectory(path.dirname(outputPath));

        if (file.endsWith("_test.dart")) {
          var statusPath = path.withoutExtension(relativePath);

          void _writeTest(String outputPath, String contents) {
            if (contents.contains('package:unittest/')) {
              // TODO(jmesserly): we could use directive parsing, but that
              // feels like overkill.
              // Alternatively, we could detect "unittest" use at runtime.
              // We really need a better solution for Karma+mocha+unittest
              // integration.
              contents += '\nfinal _usesUnittestPackage = true;\n';
            }
            new File(outputPath).writeAsStringSync(contents);
          }

          var contents = new File(file).readAsStringSync();
          if (isMultiTest(contents)) {
            // It's a multitest, so expand it and add all of the variants.
            var tests = <String, String>{};
            extractTestsFromMultitest(file, contents, tests);

            var fileName = path.basenameWithoutExtension(file);
            var outputDir = path.dirname(outputPath);
            tests.forEach((name, contents) {
              var multiFile =
                  path.join(outputDir, '${fileName}_${name}_multi.dart');
              testFiles[multiFile] =
                  expectations.expectations("$statusPath/$name");

              _writeTest(multiFile, contents);
            });
          } else {
            // It's a single test suite.
            testFiles[outputPath] = expectations.expectations(statusPath);
          }

          // Write the test file.
          //
          // We do this even for multitests because import_self_test
          // is a multitest, yet imports its own unexpanded form (!).
          _writeTest(outputPath, contents);
        } else {
          // Copy the non-test file over, in case it is used as an import.
          new File(file).copySync(outputPath);
        }
      }
    }
  }

  // Also include the other special files that live at the top level directory.
  for (var file in _listFiles(codegenDir)) {
    var relativePath = path.relative(file, from: codegenDir);
    var outputPath = path.join(codegenTestDir, relativePath);

    new File(file).copySync(outputPath);
    if (file.endsWith(".dart")) {
      testFiles[outputPath] = new Set()..add(Expectation.pass);
    }
  }

  return testFiles;
}

/// Recursively creates [dir] if it doesn't exist.
void _ensureDirectory(String dir) {
  new Directory(dir).createSync(recursive: true);
}

/// Lists all of the files within [dir] that match [filePattern].
Iterable<String> _listFiles(String dir, {bool recursive: false}) {
  return new Directory(dir)
      .listSync(recursive: recursive, followLinks: false)
      .where((e) => e is File && filePattern.hasMatch(e.path))
      .map((f) => f.path);
}

/// Parse directives from [contents] and find the complete set of transitive
/// imports, reading files as needed.
///
/// This will not include dart:* libraries, as those are implicitly available.
void _collectTransitiveImports(String contents, Set<String> libraries,
    {String packageRoot, String from}) {
  var uri = from;
  if (packageRoot != null && path.isWithin(packageRoot, from)) {
    uri = 'package:${path.relative(from, from: packageRoot)}';
  }
  if (!libraries.add(uri)) return;

  var unit = parseDirectives(contents, name: from, suppressErrors: true);
  for (var d in unit.directives) {
    if (d is NamespaceDirectiveImpl) {
      String uri = _resolveDirective(d);
      if (uri == null ||
          uri.startsWith('dart:') ||
          uri.startsWith('package:')) {
        continue;
      }

      var f = new File(path.join(path.dirname(from), uri));
      if (f.existsSync()) {
        _collectTransitiveImports(f.readAsStringSync(), libraries,
            packageRoot: packageRoot, from: f.path);
      }
    }
  }
}

/// Simplified from ParseDartTask.resolveDirective.
String _resolveDirective(NamespaceDirectiveImpl directive) {
  StringLiteral uriLiteral = directive.uri;
  String uriContent = uriLiteral.stringValue;
  if (uriContent != null) {
    uriContent = uriContent.trim();
    directive.uriContent = uriContent;
  }
  return directive.validate() == null ? uriContent : null;
}
