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

import 'package:expect/expect.dart';
import "package:async_helper/async_helper.dart";
import 'memory_compiler.dart';
import 'compiler_helper.dart' show findElement;

var SOURCES = const {
  'AddAll.dart': """
  var dictionaryA = {'string': "aString", 'int': 42, 'double': 21.5,
                     'list': []};
  var dictionaryB = {'string': "aString", 'int': 42, 'double': 21.5,
                     'list': []};
  var otherDict = {'stringTwo' : "anotherString", 'intTwo' : 84};
  var int = 0;
  var anotherInt = 0;
  var nullOrInt = 0;
  var dynamic = 0;

  main() {
    dictionaryA.addAll(otherDict);
    dictionaryB.addAll({'stringTwo' : "anotherString", 'intTwo' : 84});
    int = dictionaryB['int'];
    anotherInt = otherDict['intTwo'];
    dynamic = dictionaryA['int'];
    nullOrInt = dictionaryB['intTwo'];
  }
""",
  'Union.dart': """
  var dictionaryA = {'string': "aString", 'int': 42, 'double': 21.5,
                     'list': []};
  var dictionaryB = {'string': "aString", 'intTwo': 42, 'list': []};
  var nullOrInt = 0;
  var aString = "";
  var doubleOrNull = 22.2;
  var key = "string";

  main() {
    var union = dictionaryA['foo'] ? dictionaryA : dictionaryB;
    nullOrInt = union['intTwo'];
    aString = union['string'];
    doubleOrNull = union['double'];
  }
""",
  'ValueType.dart': """
  var dictionary = {'string': "aString", 'int': 42, 'double': 21.5, 'list': []};
  var keyD = 'double';
  var keyI = 'int';
  var keyN = 'notFoundInMap';
  var knownDouble = 42.2;
  var intOrNull = dictionary[keyI];
  var justNull = dictionary[keyN];

  main() {
    knownDouble = dictionary[keyD];
    var x = [intOrNull, justNull];
  }
""",
  'Propagation.dart': """
  class A {
    A();
    foo(value) {
      return value['anInt'];
    }
  }

  class B {
    B();
    foo(value) {
      return 0;
    }
  }

  main() {
    var dictionary = {'anInt': 42, 'aString': "theString"};
    var it;
    if ([true, false][0]) {
      it = new A();
    } else {
      it = new B();
    }
    print(it.foo(dictionary) + 2);
  }
""",
  'Bailout.dart': """
  var dict = makeMap([1,2]);
  var notInt = 0;
  var alsoNotInt = 0;

  makeMap(values) {
    return {'moo': values[0], 'boo': values[1]};
  }

  main () {
    dict['goo'] = 42;
    var closure = () => dict;
    notInt = closure()['boo'];
    alsoNotInt = dict['goo'];
    print("\$notInt and \$alsoNotInt.");
  }
"""
};

void main() {
  asyncTest(() async {
    await compileAndTest("AddAll.dart", (types, getType, compiler) {
      Expect.equals(getType('int'), types.uint31Type);
      Expect.equals(getType('anotherInt'), types.uint31Type);
      Expect.equals(getType('dynamic'), types.dynamicType);
      Expect.equals(getType('nullOrInt'), types.uint31Type.nullable());
    });
    await compileAndTest("Union.dart", (types, getType, compiler) {
      Expect.equals(getType('nullOrInt'), types.uint31Type.nullable());
      Expect
          .isTrue(getType('aString').containsOnlyString(compiler.closedWorld));
      Expect.equals(getType('doubleOrNull'), types.doubleType.nullable());
    });
    await compileAndTest("ValueType.dart", (types, getType, compiler) {
      Expect.equals(getType('knownDouble'), types.doubleType);
      Expect.equals(getType('intOrNull'), types.uint31Type.nullable());
      Expect.equals(getType('justNull'), types.nullType);
    });
    await compileAndTest("Propagation.dart", (code) {
      Expect.isFalse(code.contains("J.\$add\$ns"));
    }, createCode: true);
    await compileAndTest("Bailout.dart", (types, getType, compiler) {
      Expect.equals(getType('notInt'), types.dynamicType);
      Expect.equals(getType('alsoNotInt'), types.dynamicType);
      Expect.isFalse(getType('dict').isDictionary);
    });
  });
}

compileAndTest(source, checker, {createCode: false}) async {
  CompilationResult result = await runCompiler(
      entryPoint: Uri.parse('memory:' + source),
      memorySourceFiles: SOURCES,
      beforeRun: (compiler) {
        compiler.stopAfterTypeInference = !createCode;
      });
  var compiler = result.compiler;
  var commonMasks = compiler.closedWorld.commonMasks;
  var typesInferrer = compiler.globalInference.typesInferrerInternal;
  getType(String name) {
    var element = findElement(compiler, name);
    return typesInferrer.getTypeOfElement(element);
  }

  if (!createCode) {
    checker(commonMasks, getType, compiler);
  } else {
    var element = compiler.mainFunction;
    var code = compiler.backend.getGeneratedCode(element);
    checker(code);
  }
}
