// Copyright (c) 2013, 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:compiler/src/deferred_load.dart';
import 'package:expect/expect.dart';
import '../memory_compiler.dart';

void main() {
  asyncTest(() async {
    CompilationResult result =
        await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
    Compiler compiler = result.compiler;

    var env = compiler.backendClosedWorldForTesting.elementEnvironment;
    lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
    var main = env.mainFunction;
    Expect.isNotNull(main, "Could not find 'main'");

    var outputUnitForMember =
        compiler.backend.outputUnitData.outputUnitForMember;
    var outputUnitForClass = compiler.backend.outputUnitData.outputUnitForClass;

    var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
    var backend = compiler.backend;
    var classes = backend.emitter.neededClasses;
    var inputElement = classes.where((e) => e.name == 'InputElement').single;
    dynamic lib1 = lookupLibrary("memory:lib1.dart");
    var foo1 = env.lookupLibraryMember(lib1, "foo1");
    dynamic lib2 = lookupLibrary("memory:lib2.dart");
    var foo2 = env.lookupLibraryMember(lib2, "foo2");
    dynamic lib3 = lookupLibrary("memory:lib3.dart");
    var foo3 = env.lookupLibraryMember(lib3, "foo3");
    dynamic lib4 = lookupLibrary("memory:lib4.dart");
    var bar1 = env.lookupLibraryMember(lib4, "bar1");
    var bar2 = env.lookupLibraryMember(lib4, "bar2");

    OutputUnit ou_lib1 = outputUnitForMember(foo1);
    OutputUnit ou_lib2 = outputUnitForMember(foo2);
    OutputUnit ou_lib1_lib2 = outputUnitForMember(foo3);
    OutputUnit ou_lib4_1 = outputUnitForMember(bar1);
    OutputUnit ou_lib4_2 = outputUnitForMember(bar2);

    Expect.equals(mainOutputUnit, outputUnitForMember(main));
    Expect.notEquals(mainOutputUnit, outputUnitForMember(foo1));
    Expect.notEquals(ou_lib1, ou_lib1_lib2);
    Expect.notEquals(ou_lib2, ou_lib1_lib2);
    Expect.notEquals(ou_lib1, ou_lib2);
    Expect.notEquals(ou_lib4_1, ou_lib4_2);
    Expect.notEquals(ou_lib1, ou_lib4_2);
    // InputElement is native, so it should be in the mainOutputUnit.
    Expect.equals(mainOutputUnit, outputUnitForClass(inputElement));

    var hunksToLoad = compiler.deferredLoadTask.hunksToLoad;

    var hunksLib1 = hunksToLoad["lib1"];
    var hunksLib2 = hunksToLoad["lib2"];
    var hunksLib4_1 = hunksToLoad["lib4_1"];
    var hunksLib4_2 = hunksToLoad["lib4_2"];
    Expect.listEquals([ou_lib1_lib2, ou_lib1], hunksLib1);
    Expect.listEquals([ou_lib1_lib2, ou_lib2], hunksLib2);
    Expect.listEquals([ou_lib4_1], hunksLib4_1);
    Expect.listEquals([ou_lib4_2], hunksLib4_2);
    Expect.equals(hunksToLoad["main"], null);
  });
}

// The main library imports lib1 and lib2 deferred and use lib1.foo1 and
// lib2.foo2.  This should trigger seperate output units for main, lib1 and
// lib2.
//
// Both lib1 and lib2 import lib3 directly and
// both use lib3.foo3.  Therefore a shared output unit for lib1 and lib2 should
// be created.
//
// lib1 and lib2 also import lib4 deferred, but lib1 uses lib4.bar1 and lib2
// uses lib4.bar2.  So two output units should be created for lib4, one for each
// import.
const Map<String, String> MEMORY_SOURCE_FILES = const {
  "main.dart": """
import "dart:async";
import 'lib1.dart' deferred as lib1;
import 'lib2.dart' deferred as lib2;

void main() {
  lib1.loadLibrary().then((_) {
        lib1.foo1();
        new lib1.C();
    lib2.loadLibrary().then((_) {
        lib2.foo2();
    });
  });
}
""",
  "lib1.dart": """
library lib1;
import "dart:async";
import "dart:html";

import "lib3.dart" as l3;
import "lib4.dart" deferred as lib4_1;

class C {}

foo1() {
  new InputElement();
  lib4_1.loadLibrary().then((_) {
    lib4_1.bar1();
  });
  return () {return 1 + l3.foo3();} ();
}
""",
  "lib2.dart": """
library lib2;
import "dart:async";
import "lib3.dart" as l3;
import "lib4.dart" deferred as lib4_2;

foo2() {
  lib4_2.loadLibrary().then((_) {
    lib4_2.bar2();
  });
  return () {return 2+l3.foo3();} ();
}
""",
  "lib3.dart": """
library lib3;

foo3() {
  return () {return 3;} ();
}
""",
  "lib4.dart": """
library lib4;

bar1() {
  return "hello";
}

bar2() {
  return 2;
}
""",
};
