// 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 of the graph segmentation algorithm used by deferred loading
// to determine which elements can be deferred and which libraries
// much be included in the initial download (loaded eagerly).

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

void main() {
  asyncTest(() async {
    print('--test from kernel------------------------------------------------');
    await deferredTest1();
    await deferredTest2();
    await deferredTest3();
    await deferredTest4();
    await deferredTest5();
  });
}

deferredTest1() async {
  CompilationResult result = await runCompiler(memorySourceFiles: TEST1);

  Compiler compiler = result.compiler!;
  var closedWorld = compiler.backendClosedWorldForTesting!;
  var env = closedWorld.elementEnvironment;
  var outputUnitForMember = closedWorld.outputUnitData.outputUnitForMember;
  var mainOutputUnit = closedWorld.outputUnitData.mainOutputUnit;
  lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
  dynamic lib1 = lookupLibrary("memory:lib1.dart");
  dynamic lib2 = lookupLibrary("memory:lib2.dart");
  env.lookupLibraryMember(lib1, "foo1");
  var foo2 = env.lookupLibraryMember(lib2, "foo2")!;

  Expect.notEquals(mainOutputUnit, outputUnitForMember(foo2));
}

deferredTest2() async {
  CompilationResult result = await runCompiler(memorySourceFiles: TEST2);

  Compiler compiler = result.compiler!;
  var closedWorld = compiler.backendClosedWorldForTesting!;
  var env = closedWorld.elementEnvironment;
  var outputUnitForClass = closedWorld.outputUnitData.outputUnitForClass;
  var outputUnitForClassType =
      closedWorld.outputUnitData.outputUnitForClassType;
  lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
  dynamic shared = lookupLibrary("memory:shared.dart");
  var a = env.lookupClass(shared, "A")!;

  Expect.equals("OutputUnit(1, {import(def: deferred)})",
      outputUnitForClass(a).toString());
  Expect.equals("OutputUnit(1, {import(def: deferred)})",
      outputUnitForClassType(a).toString());
}

deferredTest3() async {
  CompilationResult result = await runCompiler(memorySourceFiles: TEST3);

  Compiler compiler = result.compiler!;
  var closedWorld = compiler.backendClosedWorldForTesting!;
  var env = closedWorld.elementEnvironment;
  var outputUnitForClass = closedWorld.outputUnitData.outputUnitForClass;
  var outputUnitForClassType =
      closedWorld.outputUnitData.outputUnitForClassType;
  var mainOutputUnit = closedWorld.outputUnitData.mainOutputUnit;
  lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
  dynamic shared = lookupLibrary("memory:shared.dart");
  var a = env.lookupClass(shared, "A")!;

  Expect.equals(mainOutputUnit, outputUnitForClass(a));
  Expect.equals(mainOutputUnit, outputUnitForClassType(a));
}

deferredTest4() async {
  CompilationResult result = await runCompiler(memorySourceFiles: TEST4);

  Compiler compiler = result.compiler!;
  var closedWorld = compiler.backendClosedWorldForTesting!;
  var env = closedWorld.elementEnvironment;
  var outputUnitForClass = closedWorld.outputUnitData.outputUnitForClass;
  var outputUnitForClassType =
      closedWorld.outputUnitData.outputUnitForClassType;
  var mainOutputUnit = closedWorld.outputUnitData.mainOutputUnit;
  lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
  dynamic shared = lookupLibrary("memory:shared.dart");
  var a = env.lookupClass(shared, "A")!;

  Expect.equals("OutputUnit(1, {import(def: deferred)})",
      outputUnitForClass(a).toString());
  Expect.equals(mainOutputUnit, outputUnitForClassType(a));
}

deferredTest5() async {
  CompilationResult result = await runCompiler(memorySourceFiles: TEST5);

  Compiler compiler = result.compiler!;
  var closedWorld = compiler.backendClosedWorldForTesting!;
  var env = closedWorld.elementEnvironment;
  var outputUnitForClass = closedWorld.outputUnitData.outputUnitForClass;
  var outputUnitForClassType =
      closedWorld.outputUnitData.outputUnitForClassType;
  lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
  dynamic shared = lookupLibrary("memory:shared.dart");
  var a = env.lookupClass(shared, "A")!;
  Expect.equals(
      "OutputUnit(4, {import(def2: deferred), import(def3: deferred)})",
      outputUnitForClass(a).toString());
  Expect.equals(
      "OutputUnit(2, {import(def1: deferred), "
      "import(def2: deferred), "
      "import(def3: deferred)})",
      outputUnitForClassType(a).toString());
}

// lib1 imports lib2 deferred. But mainlib never uses DeferredLibrary.
// Test that this case works.
const Map<String, String> TEST1 = const {
  "main.dart": """
library mainlib;

import 'lib1.dart' as lib1;

void main() {
  lib1.foo1();
}
""",
  "lib1.dart": """
library lib1;

import 'lib2.dart' deferred as lib2;

void foo1() {
  lib2.loadLibrary().then((_) => lib2.foo2());
}
""",
  "lib2.dart": """
library lib2;

void foo2() {}
""",
};

// A's type should be in main.
const Map<String, String> TEST2 = const {
  "main.dart": """
import 'def.dart' deferred as def;
import 'shared.dart';

typedef void F(x);

main() {
  print(getFoo() is F);
  def.loadLibrary().then((_) {
    def.toto();
  });
}
""",
  "def.dart": """
import 'shared.dart';

toto() { print(new A()); }
""",
  "shared.dart": """
class A {}
class B extends A {}
foo(B b) => null;
getFoo() => foo;
""",
};

// main directly uses class A from shared. A should be included in the
// main fragment.
const Map<String, String> TEST3 = const {
  "main.dart": """
import 'def.dart' deferred as def;
import 'shared.dart';

main() {
  print(A());
  def.loadLibrary().then((_) {
    def.toto();
  });
}
""",
  "def.dart": """
import 'shared.dart';

toto() { print(new A()); }
""",
  "shared.dart": """
class A {}
class B extends A {}
""",
};

// main directly uses class A's type from shared. A's type but not class
// should be included in main.
const Map<String, String> TEST4 = const {
  "main.dart": """
import 'def.dart' deferred as def;
import 'shared.dart';

main() {
  var v = 5;
  print(v is A);
  def.loadLibrary().then((_) {
    def.toto();
  });
}
""",
  "def.dart": """
import 'shared.dart';

toto() { print(new A()); }
""",
  "shared.dart": """
class A {}
""",
};

// main doesn't directly use A's class or type, but does so indirectly.
const Map<String, String> TEST5 = const {
  "main.dart": """
import 'def1.dart' deferred as def1;
import 'def2.dart' deferred as def2;
import 'def3.dart' deferred as def3;

main() {
  def1.loadLibrary().then((_) {
    def2.loadLibrary().then((_) {
      def3.loadLibrary().then((_) {
        def1.toto(null);
        def2.toto();
        def3.toto(null);
      });
    });
  });
}
""",
  "def1.dart": """
import 'shared.dart';

toto(x) => x is A;
""",
  "def2.dart": """
import 'shared.dart';

toto() { print(A()); }
""",
  "def3.dart": """
import 'shared.dart';

toto(x) {
  print(new A());
  return x is A;
}
""",
  "shared.dart": """
class A {}
""",
};
