// Copyright (c) 2018, 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:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'driver_resolution.dart';
import 'resolution.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ConstantDriverTest);
  });
}

@reflectiveTest
class ConstantDriverTest extends DriverResolutionTest with ConstantMixin {}

mixin ConstantMixin implements ResolutionTest {
  test_constantValue_defaultParameter_noDefaultValue() async {
    newFile('/test/lib/a.dart', content: r'''
class A {
  const A({int p});
}
''');
    addTestFile(r'''
import 'a.dart';
const a = const A();
''');
    await resolveTestFile();
    assertNoTestErrors();

    var aLib = findElement.import('package:test/a.dart').importedLibrary;
    var aConstructor = aLib.getType('A').constructors.single;
    DefaultParameterElementImpl p = aConstructor.parameters.single;

    // To evaluate `const A()` we have to evaluate `{int p}`.
    // Even if its value is `null`.
    expect(p.isConstantEvaluated, isTrue);
    expect(p.constantValue.isNull, isTrue);
  }

  test_constFactoryRedirection_super() async {
    addTestFile(r'''
class I {
  const factory I(int f) = B;
}

class A implements I {
  final int f;

  const A(this.f);
}

class B extends A {
  const B(int f) : super(f);
}

@I(42)
main() {}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var node = findNode.annotation('@I');
    var value = node.elementAnnotation.constantValue;
    expect(value.getField('(super)').getField('f').toIntValue(), 42);
  }

  test_constNotInitialized() async {
    addTestFile(r'''
class B {
  const B(_);
}

class C extends B {
  static const a;
  const C() : super(a);
}
''');
    await resolveTestFile();
    assertTestErrorsWithCodes([
      CompileTimeErrorCode.CONST_NOT_INITIALIZED,
      CompileTimeErrorCode.CONST_NOT_INITIALIZED,
    ]);
  }

  test_functionType_element_typeArguments() async {
    newFile('/test/lib/a.dart', content: r'''
typedef F<T> = T Function(int);
const a = C<F<double>>();

class C<T> {
  const C();
}
''');
    addTestFile(r'''
import 'a.dart';

const v = a;
''');
    await resolveTestFile();
    assertNoTestErrors();

    var v = findElement.topVar('v') as ConstVariableElement;
    var value = v.computeConstantValue();

    var type = value.type as InterfaceType;
    assertElementTypeString(type, 'C<double Function(int)>');

    expect(type.typeArguments, hasLength(1));
    var typeArgument = type.typeArguments[0] as FunctionType;
    assertElementTypeString(typeArgument, 'double Function(int)');

    // The element and type arguments are available for the function type.
    var importFind = findElement.importFind('package:test/a.dart');
    var elementF = importFind.functionTypeAlias('F');
    expect(typeArgument.element, elementF.function);
    expect(typeArgument.element.enclosingElement, elementF);
    assertElementTypeStrings(typeArgument.typeArguments, ['double']);
  }
}
