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

// Test that the CPS IR code generator compiles programs and produces the
// the expected output.

import 'dart:io';

import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:compiler/src/apiimpl.dart' show
    CompilerImpl;
import '../memory_compiler.dart';
import 'package:compiler/src/js/js.dart' as js;
import 'package:compiler/src/elements/elements.dart' show
    ClassElement,
    Element;

// Regular experession used to extract the method name that is used to match the
// test output. By default we match the output of main.
final RegExp elementNameRegExp = new RegExp(r'^// Method to test: (.*)$',
    multiLine: true);

runTest(String filename, {bool update: false}) {
  var outputname = filename.replaceFirst('.dart', '.js');
  String source = new File.fromUri(Platform.script.resolve('input/$filename'))
      .readAsStringSync();
  var expectedFile =
      new File.fromUri(Platform.script.resolve('expected/$outputname'));
  String expected = '';
  if (expectedFile.existsSync()) {
    expected = expectedFile.readAsStringSync()
      .replaceAll(new RegExp('^//.*\n', multiLine: true), '')
      .trim();
  }

  var match = elementNameRegExp.firstMatch(source);
  var elementName = match?.group(1);

  Map files = {
      TEST_MAIN_FILE: source,
      'package:expect/expect.dart': '''
          class NoInline {
            const NoInline();
          }
          class TrustTypeAnnotations {
            const TrustTypeAnnotations();
          }
          class AssumeDynamic {
            const AssumeDynamic();
          }
       ''',
   };
  asyncTest(() async {
    Uri uri = Uri.parse('memory:$TEST_MAIN_FILE');
    String found = null;
    try {
      CompilationResult result = await runCompiler(
          entryPoint: uri,
          memorySourceFiles: files,
          options: <String>['--use-cps-ir']);
      Expect.isTrue(result.isSuccess);
      CompilerImpl compiler = result.compiler;
      if (expected != null) {
        found = elementName == null
            ? _getCodeForMain(compiler)
            : _getCodeForMethod(compiler, elementName);
      }
    } catch (e, st) {
      print(e);
      print(st);
      var message = 'The following test failed to compile:\n'
                    '${_formatTest(files)}';
      if (update) {
        print('\n\n$message\n');
        return;
      } else {
        Expect.fail(message);
      }
    }
    if (expected != found) {
      if (update) {
        // Include the input in a comment of the expected file to make it easier
        // to see the relation between input and output in code reviews.
        String comment = source.trim().replaceAll('\n', '\n// ');
        expectedFile.writeAsStringSync('// Expectation for test: \n'
            '// ${comment}\n\n${found}\n');
        print('INFO: $expectedFile was updated');
      } else {
        Expect.fail('Unexpected output for test:\n  '
            '${_formatTest(files).replaceAll('\n', '\n  ')}\n'
            'Expected:\n  ${expected.replaceAll('\n', '\n  ')}\n\n'
            'but found:\n  ${found?.replaceAll('\n', '\n  ')}\n'
            '$regenerateCommand');
      }
    }
  });
}

String get regenerateCommand {
  var flags = Platform.packageRoot == null
    ? '' : '--package-root=${Platform.packageRoot} ';
  return '''
If you wish to update the test expectations, rerun this test passing "update" as
an argument, as follows:

  dart $flags${Platform.script} update

If you want to update more than one test at once, run:
  dart $flags${Platform.script.resolve('update_all.dart')}

''';
}

const String TEST_MAIN_FILE = 'test.dart';

String _formatTest(Map test) {
  return test[TEST_MAIN_FILE];
}

String _getCodeForMain(CompilerImpl compiler) {
  Element mainFunction = compiler.mainFunction;
  js.Node ast = compiler.enqueuer.codegen.generatedCode[mainFunction];
  return js.prettyPrint(ast, compiler);
}

String _getCodeForMethod(CompilerImpl compiler,
                        String name) {
  Element foundElement;
  for (Element element in compiler.enqueuer.codegen.generatedCode.keys) {
    if (element.toString() == name) {
      if (foundElement != null) {
        Expect.fail('Multiple compiled elements are called $name');
      }
      foundElement = element;
    }
  }

  if (foundElement == null) {
    Expect.fail('There is no compiled element called $name');
  }

  js.Node ast = compiler.enqueuer.codegen.generatedCode[foundElement];
  return js.prettyPrint(ast, compiler);
}
