// 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.

/// 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;

import 'dart:io';
import 'package:analyzer/src/generated/engine.dart'
    show AnalysisContext, AnalysisEngine, Logger;
import 'package:analyzer/src/generated/java_engine.dart' show CaughtException;
import 'package:args/args.dart';
import 'package:logging/logging.dart' show Level;
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

import 'package:dev_compiler/devc.dart';
import 'package:dev_compiler/src/compiler.dart' show defaultRuntimeFiles;
import 'package:dev_compiler/src/options.dart';

import 'testing.dart' show realSdkContext, testDirectory;
import 'multitest.dart';

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

final inputDir = path.join(testDirectory, 'codegen');

Iterable<String> _findTests(String dir, RegExp filePattern) {
  var files = new Directory(dir)
      .listSync()
      .where((f) => f is File)
      .map((f) => f.path)
      .where((p) => p.endsWith('.dart') && filePattern.hasMatch(p));
  if (dir != inputDir) {
    files = files
        .where((p) => p.endsWith('_test.dart') || p.endsWith('_multi.dart'));
  }
  return files;
}

main(arguments) {
  if (arguments == null) arguments = [];
  ArgResults args = argParser.parse(arguments);
  var filePattern = new RegExp(args.rest.length > 0 ? args.rest[0] : '.');
  var compilerMessages = new StringBuffer();
  var loggerSub;

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

  setUp(() {
    compilerMessages.clear();
    loggerSub = setupLogger(Level.CONFIG, compilerMessages.writeln);
  });

  tearDown(() {
    if (loggerSub != null) {
      loggerSub.cancel();
      loggerSub = null;
    }
  });

  var expectDir = path.join(inputDir, 'expect');

  BatchCompiler createCompiler(AnalysisContext context,
      {bool checkSdk: false,
      bool sourceMaps: false,
      bool closure: false,
      ModuleFormat moduleFormat: ModuleFormat.legacy}) {
    // TODO(jmesserly): add a way to specify flags in the test file, so
    // they're more self-contained.
    var runtimeDir = path.join(path.dirname(testDirectory), 'lib', 'runtime');
    var options = new CompilerOptions(
        codegenOptions: new CodegenOptions(
            outputDir: expectDir,
            emitSourceMaps: sourceMaps,
            closure: closure,
            forceCompile: checkSdk,
            moduleFormat: moduleFormat),
        useColors: false,
        checkSdk: checkSdk,
        runtimeDir: runtimeDir,
        inputBaseDir: inputDir);
    var reporter = createErrorReporter(context, options);
    return new BatchCompiler(context, options, reporter: reporter);
  }

  bool compile(BatchCompiler compiler, String filePath) {
    compiler.compileFromUriString(filePath, (String url) {
      // Write compiler messages to disk.
      var messagePath = '${path.withoutExtension(url)}.txt';
      var file = new File(messagePath);
      var message = '''
// Messages from compiling ${path.basenameWithoutExtension(url)}.dart
$compilerMessages''';
      var dir = file.parent;
      if (!dir.existsSync()) dir.createSync(recursive: true);
      file.writeAsStringSync(message);
      compilerMessages.clear();
    });
    return !compiler.failure;
  }

  var testDirs = <String>['language', path.join('lib', 'typed_data')];

  var multitests = new Set<String>();
  {
    // Expand wacky multitests into a bunch of test files.
    // We'll compile each one as if it was an input.
    for (var testDir in testDirs) {
      var fullDir = path.join(inputDir, testDir);
      var testFiles = _findTests(fullDir, filePattern);

      for (var filePath in testFiles) {
        if (filePath.endsWith('_multi.dart')) continue;

        var contents = new File(filePath).readAsStringSync();
        if (isMultiTest(contents)) {
          multitests.add(filePath);

          var tests = new Map<String, String>();
          var outcomes = new Map<String, Set<String>>();
          extractTestsFromMultitest(filePath, contents, tests, outcomes);

          var filename = path.basenameWithoutExtension(filePath);
          tests.forEach((name, contents) {
            new File(path.join(fullDir, '${filename}_${name}_multi.dart'))
                .writeAsStringSync(contents);
          });
        }
      }
    }
  }

  var batchCompiler = createCompiler(realSdkContext);

  var allDirs = [null];
  allDirs.addAll(testDirs);
  for (var dir in allDirs) {
    if (codeCoverage && dir != null) continue;

    group('dartdevc ' + path.join('test', 'codegen', dir), () {
      var outDir = new Directory(path.join(expectDir, dir));
      if (!outDir.existsSync()) outDir.createSync(recursive: true);

      var testFiles = _findTests(path.join(inputDir, dir), filePattern);
      for (var filePath in testFiles) {
        if (multitests.contains(filePath)) continue;

        var filename = path.basenameWithoutExtension(filePath);

        test('$filename.dart', () {
          // TODO(jmesserly): this was added to get some coverage of source maps
          // and closure annotations.
          // We need a more comprehensive strategy to test them.
          var sourceMaps = filename == 'map_keys';
          var closure = filename == 'closure';
          var moduleFormat = filename == 'es6_modules'
              ? ModuleFormat.es6
              : filename == 'node_modules'
                  ? ModuleFormat.node
                  : ModuleFormat.legacy;
          var success;
          // TODO(vsm): Is it okay to reuse the same context here?  If there is
          // overlap between test files, we may need separate ones for each
          // compiler.
          var compiler =
              (sourceMaps || closure || moduleFormat != ModuleFormat.legacy)
                  ? createCompiler(realSdkContext,
                      sourceMaps: sourceMaps,
                      closure: closure,
                      moduleFormat: moduleFormat)
                  : batchCompiler;
          success = compile(compiler, filePath);

          var outFile = new File(path.join(outDir.path, '$filename.js'));
          expect(!success || outFile.existsSync(), true,
              reason: '${outFile.path} was created if compilation succeeds');
        });
      }
    });
  }

  if (codeCoverage) {
    group('sdk', () {
      // The analyzer does not bubble exception messages for certain internal
      // dart:* library failures, such as failing to find
      // "_internal/libraries.dart". Instead it produces an opaque "failed to
      // instantiate dart:core" message. To remedy this we hook up an analysis
      // logger that prints these messages.
      var savedLogger;
      setUp(() {
        savedLogger = AnalysisEngine.instance.logger;
        AnalysisEngine.instance.logger = new PrintLogger();
      });
      tearDown(() {
        AnalysisEngine.instance.logger = savedLogger;
      });

      test('devc dart:core', () {
        var testSdkContext = createAnalysisContextWithSources(
            new SourceResolverOptions(
                dartSdkPath:
                    path.join(testDirectory, '..', 'tool', 'generated_sdk')));

        // Get the test SDK. We use a checked in copy so test expectations can
        // be generated against a specific SDK version.
        var compiler = createCompiler(testSdkContext, checkSdk: true);
        compile(compiler, 'dart:core');
        var outFile = new File(path.join(expectDir, 'dart/core.js'));
        expect(outFile.existsSync(), true,
            reason: '${outFile.path} was created for dart:core');
      });
    });
  }

  var expectedRuntime =
      defaultRuntimeFiles.map((f) => 'dev_compiler/runtime/$f');

  test('devc jscodegen sunflower.html', () {
    var filePath = path.join(inputDir, 'sunflower', 'sunflower.html');
    var success = compile(batchCompiler, filePath);

    var expectedFiles = ['sunflower.html', 'sunflower.js',];

    for (var filepath in expectedFiles) {
      var outFile = new File(path.join(expectDir, 'sunflower', filepath));
      expect(outFile.existsSync(), success,
          reason: '${outFile.path} was created iff compilation succeeds');
    }
  });

  test('devc jscodegen html_input.html', () {
    var filePath = path.join(inputDir, 'html_input.html');
    var success = compile(batchCompiler, filePath);

    var expectedFiles = [
      'html_input.html',
      'dir/html_input_a.js',
      'dir/html_input_b.js',
      'dir/html_input_c.js',
      'dir/html_input_d.js',
      'dir/html_input_e.js'
    ]..addAll(expectedRuntime);

    for (var filepath in expectedFiles) {
      var outFile = new File(path.join(expectDir, filepath));
      expect(outFile.existsSync(), success,
          reason: '${outFile.path} was created iff compilation succeeds');
    }
  });
}

/// An implementation of analysis engine's [Logger] that prints.
class PrintLogger implements Logger {
  @override void logError(String message, [CaughtException exception]) {
    print('[AnalysisEngine] error $message $exception');
  }

  void logInformation(String message, [CaughtException exception]) {}
  void logInformation2(String message, Object exception) {}
}
