// 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:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'parser_test_base.dart';
import 'test_support.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(GenericMetadataEnabledParserTest);
    defineReflectiveTests(GenericMetadataDisabledParserTest);
  });
}

@reflectiveTest
class GenericMetadataDisabledParserTest extends FastaParserTestCase
    with GenericMetadataParserTest {
  @override
  CompilationUnit _parseCompilationUnit(String content,
      {List<ExpectedError>? errors, required ExpectedError? disabledError}) {
    var combinedErrors =
        disabledError == null ? errors : [disabledError, ...?errors];
    return parseCompilationUnit(content,
        errors: combinedErrors,
        featureSet: FeatureSet.forTesting(sdkVersion: '2.12'));
  }
}

@reflectiveTest
class GenericMetadataEnabledParserTest extends FastaParserTestCase
    with GenericMetadataParserTest {
  @override
  CompilationUnit _parseCompilationUnit(String content,
          {List<ExpectedError>? errors,
          required ExpectedError? disabledError}) =>
      parseCompilationUnit(content,
          errors: errors,
          featureSet: FeatureSet.forTesting(
              sdkVersion: '2.12',
              additionalFeatures: [Feature.generic_metadata]));
}

mixin GenericMetadataParserTest on FastaParserTestCase {
  void test_className_prefixed_constructorName_absent() {
    var compilationUnit = _parseCompilationUnit('@p.A<B>() class C {}',
        disabledError: expectedError(
            ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 4, 1));
    var classDeclaration =
        compilationUnit.declarations.single as ClassDeclaration;
    var annotation = classDeclaration.metadata.single;
    var className = annotation.name as PrefixedIdentifier;
    expect(className.prefix.name, 'p');
    expect(className.identifier.name, 'A');
    var typeArgument = annotation.typeArguments!.arguments.single as TypeName;
    var typeArgumentName = typeArgument.name as SimpleIdentifier;
    expect(typeArgumentName.name, 'B');
    expect(annotation.constructorName, isNull);
  }

  void test_className_prefixed_constructorName_present() {
    var compilationUnit = _parseCompilationUnit('@p.A<B>.ctor() class C {}',
        disabledError: expectedError(
            ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 4, 1));
    var classDeclaration =
        compilationUnit.declarations.single as ClassDeclaration;
    var annotation = classDeclaration.metadata.single;
    var className = annotation.name as PrefixedIdentifier;
    expect(className.prefix.name, 'p');
    expect(className.identifier.name, 'A');
    var typeArgument = annotation.typeArguments!.arguments.single as TypeName;
    var typeArgumentName = typeArgument.name as SimpleIdentifier;
    expect(typeArgumentName.name, 'B');
    expect(annotation.constructorName!.name, 'ctor');
  }

  void test_className_unprefixed_constructorName_absent() {
    var compilationUnit = _parseCompilationUnit('@A<B>() class C {}',
        disabledError: expectedError(
            ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 2, 1));
    var classDeclaration =
        compilationUnit.declarations.single as ClassDeclaration;
    var annotation = classDeclaration.metadata.single;
    var className = annotation.name as SimpleIdentifier;
    expect(className.name, 'A');
    var typeArgument = annotation.typeArguments!.arguments.single as TypeName;
    var typeArgumentName = typeArgument.name as SimpleIdentifier;
    expect(typeArgumentName.name, 'B');
    expect(annotation.constructorName, isNull);
  }

  void test_className_unprefixed_constructorName_present() {
    var compilationUnit = _parseCompilationUnit('@A<B>.ctor() class C {}',
        disabledError: expectedError(
            ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 2, 1));
    var classDeclaration =
        compilationUnit.declarations.single as ClassDeclaration;
    var annotation = classDeclaration.metadata.single;
    var className = annotation.name as SimpleIdentifier;
    expect(className.name, 'A');
    var typeArgument = annotation.typeArguments!.arguments.single as TypeName;
    var typeArgumentName = typeArgument.name as SimpleIdentifier;
    expect(typeArgumentName.name, 'B');
    expect(annotation.constructorName!.name, 'ctor');
  }

  void test_reference_prefixed() {
    var compilationUnit = _parseCompilationUnit('@p.x<A> class C {}',
        errors: [
          expectedError(
              ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS_UNINSTANTIATED,
              6,
              1),
        ],
        disabledError: expectedError(
            ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 4, 1));
    var classDeclaration =
        compilationUnit.declarations.single as ClassDeclaration;
    var annotation = classDeclaration.metadata.single;
    var name = annotation.name as PrefixedIdentifier;
    expect(name.prefix.name, 'p');
    expect(name.identifier.name, 'x');
    var typeArgument = annotation.typeArguments!.arguments.single as TypeName;
    var typeArgumentName = typeArgument.name as SimpleIdentifier;
    expect(typeArgumentName.name, 'A');
    expect(annotation.constructorName, isNull);
  }

  void test_reference_unprefixed() {
    var compilationUnit = _parseCompilationUnit('@x<A> class C {}',
        errors: [
          expectedError(
              ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS_UNINSTANTIATED,
              4,
              1),
        ],
        disabledError: expectedError(
            ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 2, 1));
    var classDeclaration =
        compilationUnit.declarations.single as ClassDeclaration;
    var annotation = classDeclaration.metadata.single;
    var name = annotation.name as SimpleIdentifier;
    expect(name.name, 'x');
    var typeArgument = annotation.typeArguments!.arguments.single as TypeName;
    var typeArgumentName = typeArgument.name as SimpleIdentifier;
    expect(typeArgumentName.name, 'A');
    expect(annotation.constructorName, isNull);
  }

  test_typeArguments_after_constructorName() {
    _parseCompilationUnit('@p.A.ctor<B>() class C {}',
        errors: [
          expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 9, 1),
          expectedError(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 10, 1),
          expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 1),
          expectedError(ParserErrorCode.TOP_LEVEL_OPERATOR, 11, 1),
          expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 15, 5),
        ],
        disabledError: null);
  }

  test_typeArguments_after_prefix() {
    _parseCompilationUnit('@p<A>.B.ctor() class C {}',
        errors: [
          expectedError(
              ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS_UNINSTANTIATED,
              6,
              1),
          expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 7, 1),
          expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 15, 5),
        ],
        disabledError: expectedError(
            ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 2, 1));
  }

  CompilationUnit _parseCompilationUnit(String content,
      {List<ExpectedError>? errors, required ExpectedError? disabledError});
}
