// 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/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'context_collection_resolution.dart';

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

@reflectiveTest
class OptionalConstDriverResolutionTest extends PubPackageResolutionTest {
  Map<String, LibraryElement> libraries = {};

  LibraryElement get libraryA => libraries['package:test/a.dart']!;

  test_instantiateToBounds_notPrefixed_named() async {
    var creation = await _resolveImplicitConst('B.named()');
    assertInstanceCreation(
      creation,
      libraryA.getType('B')!,
      'B<num>',
      constructorName: 'named',
      expectedConstructorMember: true,
      expectedSubstitution: {'T': 'num'},
    );
  }

  test_instantiateToBounds_notPrefixed_unnamed() async {
    var creation = await _resolveImplicitConst('B()');
    assertInstanceCreation(
      creation,
      libraryA.getType('B')!,
      'B<num>',
      expectedConstructorMember: true,
      expectedSubstitution: {'T': 'num'},
    );
  }

  test_instantiateToBounds_prefixed_named() async {
    var creation = await _resolveImplicitConst('p.B.named()', prefix: 'p');
    assertInstanceCreation(
      creation,
      libraryA.getType('B')!,
      'B<num>',
      constructorName: 'named',
      expectedConstructorMember: true,
      expectedSubstitution: {'T': 'num'},
      expectedPrefix: _importOfA().prefix,
    );
  }

  test_instantiateToBounds_prefixed_unnamed() async {
    var creation = await _resolveImplicitConst('p.B()', prefix: 'p');
    assertInstanceCreation(
      creation,
      libraryA.getType('B')!,
      'B<num>',
      expectedConstructorMember: true,
      expectedSubstitution: {'T': 'num'},
      expectedPrefix: _importOfA().prefix,
    );
  }

  test_notPrefixed_named() async {
    var creation = await _resolveImplicitConst('A.named()');
    assertInstanceCreation(
      creation,
      libraryA.getType('A')!,
      'A',
      constructorName: 'named',
    );
  }

  test_notPrefixed_unnamed() async {
    var creation = await _resolveImplicitConst('A()');
    assertInstanceCreation(
      creation,
      libraryA.getType('A')!,
      'A',
    );
  }

  test_prefixed_named() async {
    var creation = await _resolveImplicitConst('p.A.named()', prefix: 'p');
    // Note, that we don't resynthesize the import prefix.
    assertInstanceCreation(
      creation,
      libraryA.getType('A')!,
      'A',
      constructorName: 'named',
      expectedPrefix: _importOfA().prefix,
    );
  }

  test_prefixed_unnamed() async {
    var creation = await _resolveImplicitConst('p.A()', prefix: 'p');
    // Note, that we don't resynthesize the import prefix.
    assertInstanceCreation(
      creation,
      libraryA.getType('A')!,
      'A',
      expectedPrefix: _importOfA().prefix,
    );
  }

  test_prefixed_unnamed_generic() async {
    newFile('$testPackageLibPath/a.dart', content: r'''
class C<T> {
  const C();
}
''');
    await assertNoErrorsInCode(r'''
import 'a.dart' as p;

const x = p.C<int>();
''');
    _fillLibraries();

    var element_C = libraryA.getType('C');
    var element_p = findElement.prefix('p');

    var creation = findNode.instanceCreation('p.C<int>()');
    assertType(creation, 'C<int>');

    var constructorName = creation.constructorName;

    var typeName = constructorName.type;
    assertType(typeName, 'C<int>');

    var pC = typeName.name as PrefixedIdentifier;
    assertElement(pC, element_C);
    // TODO(scheglov) enforce
//    assertTypeNull(pC);

    var ref_p = pC.prefix;
    assertElement(ref_p, element_p);
    assertTypeNull(ref_p);

    var ref_C = pC.identifier;
    assertElement(ref_C, element_C);
    assertTypeNull(ref_C);

    assertType(typeName.typeArguments!.arguments[0], 'int');
  }

  void _fillLibraries([LibraryElement? library]) {
    library ??= result.unit.declaredElement!.library;
    var uriStr = library.source.uri.toString();
    if (!libraries.containsKey(uriStr)) {
      libraries[uriStr] = library;
      library.importedLibraries.forEach(_fillLibraries);
    }
  }

  ImportElement _importOfA() {
    var importOfB = findElement.import('package:test/b.dart');
    return importOfB.importedLibrary!.imports[0];
  }

  Future<InstanceCreationExpression> _resolveImplicitConst(String expr,
      {String? prefix}) async {
    newFile('$testPackageLibPath/a.dart', content: '''
class A {
  const A();
  const A.named();
}
class B<T extends num> {
  const B();
  const B.named();
}
''');

    if (prefix != null) {
      newFile('$testPackageLibPath/b.dart', content: '''
import 'a.dart' as $prefix;
const a = $expr;
''');
    } else {
      newFile('$testPackageLibPath/b.dart', content: '''
import 'a.dart';
const a = $expr;
''');
    }

    await resolveTestCode(r'''
import 'b.dart';
var v = a;
''');
    _fillLibraries();

    var vg = findNode.simple('a;').staticElement as PropertyAccessorElement;
    var v = vg.variable as ConstVariableElement;

    var creation = v.constantInitializer as InstanceCreationExpression;
    return creation;
  }
}
