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