// 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> {}

class GenericMultiMixin<T, S> {}
class GenericSub<T, S> = Object with GenericMultiMixin<T, S>;
class FixedSub = Object with GenericMultiMixin<int, String>;


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();

  new GenericSub<int, String>();
  new FixedSub();
}
'''
};

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: entryPoint,
        memorySourceFiles: {},
        options: [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.entityEntityEquivalence);
      InterfaceType thisType1 = types1.getThisType(cls1);
      InterfaceType thisType2 = types2.getThisType(cls2);
      check(cls1, cls2, 'thisType', thisType1, thisType2,
          equivalence.typeTypeEquivalence);
      check(cls1, cls2, 'supertype', types1.getSupertype(cls1),
          types2.getSupertype(cls2), equivalence.typeTypeEquivalence);
      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.typeTypeEquivalence);

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

      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);
    });
  });
}
