// 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:pub_semver/pub_semver.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.fromEnableFlags2(
        sdkLanguageVersion: Version.parse('2.12.0'),
        flags: [],
      ),
    );
  }
}

@reflectiveTest
class GenericMetadataEnabledParserTest extends FastaParserTestCase
    with GenericMetadataParserTest {
  @override
  CompilationUnit _parseCompilationUnit(String content,
          {List<ExpectedError>? errors,
          required ExpectedError? disabledError}) =>
      parseCompilationUnit(content, errors: errors);
}

mixin GenericMetadataParserTest on FastaParserTestCase {
  void test_className_prefixed_constructorName_absent() {
    var compilationUnit = _parseCompilationUnit('@p.A<B>() class C {}',
        disabledError:
            expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 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 NamedType;
    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.EXPERIMENT_NOT_ENABLED, 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 NamedType;
    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.EXPERIMENT_NOT_ENABLED, 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 NamedType;
    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.EXPERIMENT_NOT_ENABLED, 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 NamedType;
    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.EXPERIMENT_NOT_ENABLED, 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 NamedType;
    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.EXPERIMENT_NOT_ENABLED, 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 NamedType;
    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.EXPERIMENT_NOT_ENABLED, 2, 1));
  }

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