// Copyright (c) 2017, 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 optimized algorithm for mixin applications matches the mixins
// generated by fasta.
library dart2js.kernel.mixins_test;

import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
import 'package:compiler/src/resolution/class_hierarchy.dart';
import 'package:compiler/src/universe/class_set.dart';
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
import '../memory_compiler.dart';
import '../equivalence/check_helpers.dart';
import 'test_helpers.dart';
import 'compiler_helper.dart';

const SOURCE = const {
  'main.dart': '''

class Super {}
class Mixin1 {}
class Mixin2 {}
class Sub1 extends Super with Mixin1 {}
class Sub2 extends Super with Mixin1, Mixin2 {}
class NamedSub1 = Super with Mixin1;
class NamedSub2 = Super with Mixin1, Mixin2;


class GenericSuper<T> {}
class GenericMixin1<T> {}
class GenericMixin2<T> {}
class GenericSub1<T> extends GenericSuper<T> with GenericMixin1<T> {}
class GenericSub2<T> extends GenericSuper<T>
    with GenericMixin1<T>, GenericMixin2<T> {}
class GenericNamedSub1<T> = GenericSuper<T> with GenericMixin1<T>;
class GenericNamedSub2<T> = GenericSuper<T>
    with GenericMixin1<T>, GenericMixin2<T>;

class FixedSub1a extends GenericSuper<int> with GenericMixin1<int> {}
class FixedSub1b extends GenericSuper<int> with GenericMixin1<double> {}
class FixedSub2a extends GenericSuper<int>
    with GenericMixin1<int>, GenericMixin2<int> {}
class FixedSub2b extends GenericSuper<double>
    with GenericMixin1<double>, GenericMixin2<double> {}


main() {
  new Super();
  new Mixin1();
  new Mixin2();
  new Sub1();
  new Sub2();
  new NamedSub1();
  new NamedSub2();

  new GenericSuper<int>();
  new GenericMixin1<int>();
  new GenericMixin2<int>();
  new GenericSub1<int>();
  new GenericSub2<int>();
  new GenericNamedSub1<int>();
  new GenericNamedSub2<int>();

  new FixedSub1a();
  new FixedSub1b();
  new FixedSub2a();
  new FixedSub2b();
}
'''
};

Map<ClassEntity, String> generateClassEnv(
    ElementEnvironment env, DartTypes types) {
  Map<ClassEntity, String> classEnv = <ClassEntity, String>{};

  void createEnv(ClassEntity cls) {
    classEnv.putIfAbsent(cls, () {
      InterfaceType thisType = env.getThisType(cls);
      StringBuffer sb = new StringBuffer();
      sb.write('class ');
      sb.write(env.getThisType(cls));
      ClassEntity superclass = env.getSuperClass(cls);
      if (superclass != null) {
        createEnv(superclass);
        sb.write(' extends ');
        sb.write(types.asInstanceOf(thisType, superclass));
      }
      return sb.toString();
    });
  }

  env.forEachClass(env.mainLibrary, createEnv);

  return classEnv;
}

main(List<String> args) {
  asyncTest(() async {
    useOptimizedMixins = true;

    Uri entryPoint = await createTemp(Uri.parse('memory:main.dart'), SOURCE,
        printSteps: true);

    print(
        '---- compiler from ast -----------------------------------------------');
    var result =
        await runCompiler(entryPoint: entryPoint, options: [Flags.analyzeOnly]);
    Compiler compiler1 = result.compiler;

    Compiler compiler2 = await compileWithDill(
        entryPoint, {}, [Flags.analyzeOnly],
        printSteps: true);

    ElementEnvironment env1 = compiler1.frontendStrategy.elementEnvironment;
    DartTypes types1 = compiler1.frontendStrategy.dartTypes;
    ClosedWorld closedWorld1 = compiler1.resolutionWorldBuilder.closeWorld();

    KernelFrontEndStrategy frontendStrategy = compiler2.frontendStrategy;
    ElementEnvironment env2 = frontendStrategy.elementEnvironment;
    DartTypes types2 = frontendStrategy.dartTypes;
    ClosedWorld closedWorld2 = compiler2.resolutionWorldBuilder.closeWorld();

    KernelEquivalence equivalence =
        new KernelEquivalence(frontendStrategy.elementMap);

    if (args.contains('-v')) {
      Map<ClassEntity, String> classEnv1 = generateClassEnv(env1, types1);
      Map<ClassEntity, String> classEnv2 = generateClassEnv(env2, types2);

      print('----');
      classEnv1.forEach((ClassEntity cls, String env) {
        print(env);
      });
      print('----');
      classEnv2.forEach((ClassEntity cls, String env) {
        print(env);
      });
    }

    void checkClasses(ClassEntity cls1, ClassEntity cls2) {
      if (cls1 == cls2) return;
      Expect.isNotNull(cls1, 'Missing class ${cls2.name}');
      Expect.isNotNull(cls2, 'Missing class ${cls1.name}');

      check(cls1.library, cls2.library, 'class ${cls1.name}', cls1, cls2,
          equivalence.entityEquivalence);
      InterfaceType thisType1 = types1.getThisType(cls1);
      InterfaceType thisType2 = types2.getThisType(cls2);
      check(cls1, cls2, 'thisType', thisType1, thisType2,
          equivalence.typeEquivalence);
      check(cls1, cls2, 'supertype', types1.getSupertype(cls1),
          types2.getSupertype(cls2), equivalence.typeEquivalence);
      checkClasses(env1.getSuperClass(cls1), env2.getSuperClass(cls2));

      List<DartType> mixins1 = <DartType>[];
      env1.forEachMixin(cls1, (ClassEntity mixin) {
        mixins1.add(types1.asInstanceOf(thisType1, mixin));
      });
      List<DartType> mixins2 = <DartType>[];
      env2.forEachMixin(cls2, (ClassEntity mixin) {
        mixins2.add(types2.asInstanceOf(thisType2, mixin));
      });
      checkLists(
          mixins1, mixins2, '${cls1.name} mixins', equivalence.typeEquivalence);

      checkLists(
          types1.getInterfaces(cls1).toList(),
          types2.getInterfaces(cls2).toList(),
          '${cls1.name} interfaces',
          equivalence.typeEquivalence);
      checkLists(
          types1.getSupertypes(cls1).toList(),
          types2.getSupertypes(cls2).toList(),
          '${cls1.name} supertypes',
          equivalence.typeEquivalence);

      if (cls1 == compiler1.frontendStrategy.commonElements.objectClass) return;

      ClassHierarchyNode node1 = closedWorld1.getClassHierarchyNode(cls1);
      ClassHierarchyNode node2 = closedWorld2.getClassHierarchyNode(cls2);
      checkSets(
          new Set.from(node1.directSubclasses),
          new Set.from(node2.directSubclasses),
          '${cls1.name} direct subclasses',
          (a, b) => equivalence.entityEquivalence(a.cls, b.cls));
    }

    env1.forEachClass(env1.mainLibrary, (ClassEntity cls1) {
      ClassEntity cls2 = env2.lookupClass(env2.mainLibrary, cls1.name);
      checkClasses(cls1, cls2);
    });
  });
}
