// Copyright (c) 2014, 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 additional runtime type support is output to the right
// Files when using deferred loading.

import 'package:async_helper/async_helper.dart';
import 'package:compiler/compiler_new.dart';
import 'package:compiler/src/compiler.dart';
import 'package:expect/expect.dart';
import 'memory_compiler.dart';
import 'output_collector.dart';

void main() {
  asyncTest(() async {
    OutputCollector collector = new OutputCollector();
    CompilationResult result = await runCompiler(
        memorySourceFiles: MEMORY_SOURCE_FILES, outputProvider: collector);
    Compiler compiler = result.compiler;

    lookupLibrary(name) {
      return compiler.libraryLoader.lookupLibrary(Uri.parse(name));
    }

    var main = compiler.frontendStrategy.elementEnvironment.mainFunction;
    Expect.isNotNull(main, "Could not find 'main'");
    compiler.deferredLoadTask.onResolutionComplete(
        main, compiler.resolutionWorldBuilder.closedWorldForTesting);

    var outputUnitForEntity = compiler.deferredLoadTask.outputUnitForEntity;

    dynamic lib1 = lookupLibrary("memory:lib1.dart");
    var foo1 = lib1.find("foo");
    var ou_lib1 = outputUnitForEntity(foo1);

    dynamic lib2 = lookupLibrary("memory:lib2.dart");
    var foo2 = lib2.find("foo");
    var ou_lib2 = outputUnitForEntity(foo2);

    dynamic mainApp = compiler.frontendStrategy.elementEnvironment.mainLibrary;
    var fooMain = mainApp.find("foo");
    var ou_lib1_lib2 = outputUnitForEntity(fooMain);

    String mainOutput = collector.getOutput("", OutputType.js);
    String lib1Output =
        collector.getOutput("out_${ou_lib1.name}", OutputType.jsPart);
    String lib2Output =
        collector.getOutput("out_${ou_lib2.name}", OutputType.jsPart);
    String lib12Output =
        collector.getOutput("out_${ou_lib1_lib2.name}", OutputType.jsPart);
    // Test that the deferred constants are not inlined into the main file.
    RegExp re1 = new RegExp(r"= .string1");
    RegExp re2 = new RegExp(r"= .string2");
    RegExp re3 = new RegExp(r"= 1010");
    Expect.isTrue(re1.hasMatch(lib1Output));
    Expect.isTrue(re2.hasMatch(lib1Output));
    Expect.isTrue(re3.hasMatch(lib1Output));
    Expect.isFalse(re1.hasMatch(mainOutput));
    Expect.isFalse(re2.hasMatch(mainOutput));
    Expect.isFalse(re3.hasMatch(mainOutput));
    // Test that the non-deferred constant is inlined.
    Expect.isTrue(new RegExp(r"print\(.string3.\)").hasMatch(mainOutput));
    Expect.isFalse(new RegExp(r"= .string3").hasMatch(mainOutput));
    Expect.isTrue(new RegExp(r"print\(.string4.\)").hasMatch(mainOutput));

    // C(1) is shared between main, lib1 and lib2. Test that lib1 and lib2 each
    // has a reference to it. It is defined in the main output file.
    Expect.isTrue(new RegExp(r"C.C_1 =").hasMatch(mainOutput));
    Expect.isFalse(new RegExp(r"= C.C_1").hasMatch(mainOutput));

    Expect.isTrue(new RegExp(r"= C.C_1").hasMatch(lib1Output));
    Expect.isTrue(new RegExp(r"= C.C_1").hasMatch(lib2Output));

    // C(2) is shared between lib1 and lib2, each of them has their own
    // reference to it.
    Expect.isFalse(new RegExp(r"= C.C_2").hasMatch(mainOutput));

    Expect.isTrue(new RegExp(r"= C.C_2").hasMatch(lib1Output));
    Expect.isTrue(new RegExp(r"= C.C_2").hasMatch(lib2Output));
    Expect.isTrue(new RegExp(r"C.C_2 =").hasMatch(lib12Output));

    // "string4" is shared between lib1 and lib2, but it can be inlined.
    Expect.isTrue(new RegExp(r"= .string4").hasMatch(lib1Output));
    Expect.isTrue(new RegExp(r"= .string4").hasMatch(lib2Output));
    Expect.isFalse(new RegExp(r"= .string4").hasMatch(lib12Output));
  });
}

// Make sure that deferred constants are not inlined into the main hunk.
const Map MEMORY_SOURCE_FILES = const {
  "main.dart": """
import "dart:async";

import 'lib1.dart' deferred as lib1;
import 'lib2.dart' deferred as lib2;

const c = "string3";

class C {
  final p;
  const C(this.p);
}

foo() => print("main");

void main() {
  lib1.loadLibrary().then((_) {
    lib2.loadLibrary().then((_) {
      lib1.foo();
      lib2.foo();
      print(lib1.C1);
      print(lib1.C2);
      print(lib1.C.C3);
      print(c);
      print(lib1.C4);
      print(lib2.C4);
      print(lib1.C5);
      print(lib2.C5);
      print(lib1.C6);
      print(lib2.C6);
      print("string4");
      print(const C(1));
    });
  });
}
""",
  "lib1.dart": """
import "main.dart" as main;
const C1 = "string1";
const C2 = 1010;
class C {
  static const C3 = "string2";
}
const C4 = "string4";
const C5 = const main.C(1);
const C6 = const main.C(2);
foo() {
  print("lib1");
  main.foo();
}
""",
  "lib2.dart": """
import "main.dart" as main;
const C4 = "string4";
const C5 = const main.C(1);
const C6 = const main.C(2);
foo() {
  print("lib2");
  main.foo();
}
"""
};
