// Copyright (c) 2020, 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:compiler/src/common.dart';
import 'package:compiler/src/common/elements.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/inferrer/powersets/powersets.dart';
import 'package:compiler/src/inferrer/powersets/powerset_bits.dart';
import 'package:compiler/src/js_model/js_world.dart' show JClosedWorld;
import 'package:expect/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:compiler/src/util/memory_compiler.dart';

const String CODE = """
class A {}
main() {
  A a = A();
}
""";

main() {
  retainDataForTesting = true;

  runTests() async {
    CompilationResult result = await runCompiler(
      memorySourceFiles: {'main.dart': CODE},
      options: ['--experimental-powersets'],
    );
    Expect.isTrue(result.isSuccess);
    Compiler compiler = result.compiler!;
    var results = compiler.globalInference.resultsForTesting!;
    JClosedWorld closedWorld = results.closedWorld;
    CommonElements commonElements = closedWorld.commonElements;
    ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
    final powersetDomain = closedWorld.abstractValueDomain as PowersetDomain;
    PowersetBitsDomain powersetBitsDomain = powersetDomain.powersetBitsDomain;

    var exactTrue = powersetBitsDomain.trueValue;
    var exactFalse = powersetBitsDomain.falseValue;
    dynamic classA = elementEnvironment.lookupClass(
      elementEnvironment.mainLibrary!,
      'A',
    );
    var exactA = powersetBitsDomain.createNonNullExact(classA);
    var subtypeObject = powersetBitsDomain.createNonNullSubtype(
      commonElements.objectClass,
    );
    var exactNull = powersetBitsDomain.createNonNullExact(
      commonElements.jsNullClass,
    );
    var exactBool = powersetBitsDomain.createNonNullExact(
      commonElements.jsBoolClass,
    );
    var nullableBool = powersetBitsDomain.createNullableExact(
      commonElements.jsBoolClass,
    );

    var unionTrueFalse = powersetBitsDomain.union(exactTrue, exactFalse);
    var unionBoolNull = powersetBitsDomain.union(exactBool, exactNull);
    var unionBoolNullOther = powersetBitsDomain.union(unionBoolNull, exactA);

    Expect.equals(unionTrueFalse, exactBool);
    Expect.equals(unionBoolNull, nullableBool);
    Expect.equals(unionBoolNullOther, powersetBitsDomain.powersetTop);

    checkDisjoint(int v1, int v2) {
      Expect.isTrue(powersetBitsDomain.areDisjoint(v1, v2).isDefinitelyTrue);
    }

    checkDisjoint(exactTrue, exactFalse);
    checkDisjoint(exactA, exactNull);
    checkDisjoint(subtypeObject, exactNull);
    checkDisjoint(exactBool, exactNull);
    checkDisjoint(exactA, exactBool);
    checkDisjoint(exactA, nullableBool);

    checkisIn(int v1, int v2) {
      Expect.isTrue(powersetBitsDomain.isIn(v1, v2).isDefinitelyTrue);
    }

    checkisIn(exactTrue, exactBool);
    checkisIn(exactFalse, exactBool);
    checkisIn(exactNull, nullableBool);
    checkisIn(exactBool, nullableBool);
  }

  asyncTest(() async {
    print('--test from kernel------------------------------------------------');
    await runTests();
  });
}
