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

// Test that the CPS IR code generator generates source information.

library source_information_tests;

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/cps_ir/cps_ir_nodes.dart' as ir;
import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart' as ir;
import 'package:compiler/src/js/js.dart' as js;
import 'package:compiler/src/js_backend/js_backend.dart';
import 'package:compiler/src/elements/elements.dart';

const String TEST_MAIN_FILE = 'test.dart';

class TestEntry {
  final String source;
  final List<String> expectation;
  final String elementName;

  const TestEntry(this.source, this.expectation)
    : elementName = null;

  const TestEntry.forMethod(this.elementName,
      this.source, this.expectation);
}

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

js.Node getCodeForMain(CompilerImpl compiler) {
  Element mainFunction = compiler.mainFunction;
  return compiler.enqueuer.codegen.generatedCode[mainFunction];
}

js.Node getJsNodeForElement(CompilerImpl compiler, Element element) {
  return compiler.enqueuer.codegen.generatedCode[element];
}

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);
}

runTests(List<TestEntry> tests) {
  for (TestEntry test in tests) {
    Map files = {TEST_MAIN_FILE: test.source};
    asyncTest(() {
      CompilerImpl compiler = compilerFor(
          memorySourceFiles: files, options: <String>['--use-cps-ir']);
      ir.FunctionDefinition irNodeForMain;

      void cacheIrNodeForMain(Element function, ir.FunctionDefinition irNode) {
        if (function == compiler.mainFunction) {
          assert(irNodeForMain == null);
          irNodeForMain = irNode;
        }
      }

      Uri uri = Uri.parse('memory:$TEST_MAIN_FILE');
      JavaScriptBackend backend = compiler.backend;
      var functionCompiler = backend.functionCompiler;
      functionCompiler.cpsBuilderTask.builderCallback = cacheIrNodeForMain;

      return compiler.run(uri).then((bool success) {
        Expect.isTrue(success);

        IrSourceInformationVisitor irVisitor = new IrSourceInformationVisitor();
        irNodeForMain.accept(irVisitor);

        js.Node jsNode = getJsNodeForElement(compiler, compiler.mainFunction);
        JsSourceInformationVisitor jsVisitor = new JsSourceInformationVisitor();
        jsNode.accept(jsVisitor);

        List<String> expectation = test.expectation;
        // Visiting of CPS is in structural order so we check for set equality.
        Expect.setEquals(expectation, irVisitor.sourceInformation,
              'Unexpected IR source information. '
              'Expected:\n$expectation\n'
              'but found\n${irVisitor.sourceInformation}\n'
              'in\n${test.source}'
              'CPS:\n${irNodeForMain.accept(new ir.SExpressionStringifier())}');
        Expect.listEquals(expectation, jsVisitor.sourceInformation,
              'Unexpected JS source information. '
              'Expected:\n$expectation\n'
              'but found\n${jsVisitor.sourceInformation}\n'
              'in\n${test.source}');
      }).catchError((e) {
        print(e);
        Expect.fail('The following test failed to compile:\n'
                    '${formatTest(files)}');
      });
    });
  }
}

class JsSourceInformationVisitor extends js.BaseVisitor {
  List<String> sourceInformation = <String>[];

  @override
  visitCall(js.Call node) {
    sourceInformation.add('${node.sourceInformation}');
    super.visitCall(node);
  }
}

class IrSourceInformationVisitor extends ir.TrampolineRecursiveVisitor {
  List<String> sourceInformation = <String>[];

  @override
  processInvokeStatic(ir.InvokeStatic node) {
    sourceInformation.add('${node.sourceInformation}');
  }
}

const List<TestEntry> tests = const [
  const TestEntry("""
main() { print('Hello World'); }
""", const ['memory:test.dart:[1,10]']),
const TestEntry("""
main() {
  print('Hello');
  print('World');
}
""", const ['memory:test.dart:[2,3]',
            'memory:test.dart:[3,3]']),
];

void main() {
  runTests(tests);
}
