// Copyright (c) 2024, 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.

/// 'type_analyzer_operations.dart' does support variance in some ways, but
/// this may not be supported for use in a lint. This library provides a
/// minimal level of support for variance related checks.
library;

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
// ignore: implementation_imports
import 'package:analyzer/src/dart/element/element.dart'
    show TypeParameterFragmentImpl;

enum Variance {
  out,
  in_,
  inout;

  Variance get inverse => switch (this) {
    out => in_,
    in_ => out,
    inout => inout,
  };
}

/// Iterate over a type annotation, keeping track of variance.
///
/// This class provides methods that will iterate over the parts of a given
/// [TypeAnnotation], keeping track of the variance of the position of this
/// type annotation, and invoke the hook [checkNamedType] on each [NamedType]
/// it encounters. This can be used to perform static checks on the named
/// type and the variance of the position where it occurs.
abstract class VarianceChecker {
  /// Check [typeAnnotation], using [variance] as the initial variance.
  void check(Variance variance, TypeAnnotation? typeAnnotation) {
    if (typeAnnotation == null) return;
    // Do not lint implicit program elements.
    if (typeAnnotation.isSynthetic) return;
    switch (typeAnnotation) {
      case NamedType():
        var arguments = typeAnnotation.typeArguments?.arguments;
        if (arguments != null) {
          var element = typeAnnotation.element?.baseElement;
          List<TypeParameterElement>? typeParameterList;
          if (element != null) {
            switch (element) {
              case ClassElement(:var typeParameters):
              case MixinElement(:var typeParameters):
              case EnumElement(:var typeParameters):
              case TypeAliasElement(:var typeParameters):
                typeParameterList = typeParameters;
              default:
                typeParameterList = null;
            }
          } else {
            typeParameterList = null;
          }
          if (typeParameterList == null ||
              typeParameterList.length != arguments.length) {
            // This is code with errors. Use a backup strategy:
            // Assume that every type parameter is covariant.
            for (var argument in arguments) {
              check(variance, argument);
            }
          } else {
            var length = arguments.length;
            for (var i = 0; i < length; ++i) {
              var parameter = typeParameterList[i];
              var argument = arguments[i];
              Variance parameterVariance;
              var parameterFragment =
                  parameter.firstFragment as TypeParameterFragmentImpl;
              var parameterElement = parameterFragment.element;
              if (parameterElement.isLegacyCovariant ||
                  parameterElement.variance.isCovariant) {
                parameterVariance = variance;
              } else if (parameterElement.variance.isContravariant) {
                parameterVariance = variance.inverse;
              } else {
                parameterVariance = Variance.inout;
              }
              check(parameterVariance, argument);
            }
          }
        }
        var staticType = typeAnnotation.type;
        if (staticType == null) return;
        checkNamedType(variance, staticType, typeAnnotation);
      case GenericFunctionType():
        check(variance, typeAnnotation.returnType);
        typeAnnotation.typeParameters?.typeParameters.forEach(checkBound);
        for (var parameter in typeAnnotation.parameters.parameters) {
          checkFormalParameter(variance.inverse, parameter);
        }
      case RecordTypeAnnotation():
        var positionalFields = typeAnnotation.positionalFields;
        for (var field in positionalFields) {
          check(variance, field.type);
        }
        var namedFields = typeAnnotation.namedFields?.fields;
        if (namedFields != null) {
          for (var field in namedFields) {
            check(variance, field.type);
          }
        }
    }
  }

  /// Check [typeParameter].
  ///
  /// Check the given [typeParameter], using [Variance.inout]
  /// as the initial variance (which is the only possibility).
  void checkBound(TypeParameter typeParameter) =>
      checkInOut(typeParameter.bound);

  /// Check [formalParameter], using [variance] as the initial variance.
  void checkFormalParameter(
    Variance variance,
    FormalParameter formalParameter,
  ) {
    if (!formalParameter.isExplicitlyTyped) return;
    switch (formalParameter) {
      case SuperFormalParameter(:var type):
      case FieldFormalParameter(:var type):
      case SimpleFormalParameter(:var type):
        check(variance, type);
      case FunctionTypedFormalParameter(
        :var returnType,
        :var parameters,
        :var typeParameters,
      ):
        check(variance, returnType);
        typeParameters?.typeParameters.forEach(checkBound);
        for (var parameter in parameters.parameters) {
          checkFormalParameter(variance.inverse, parameter);
        }
      case DefaultFormalParameter():
        checkFormalParameter(variance, formalParameter.parameter);
    }
  }

  /// Check [formalParameter], using [Variance.in_] as the initial variance.
  void checkFormalParameterIn(FormalParameter formalParameter) =>
      checkFormalParameter(Variance.in_, formalParameter);

  /// Check [typeAnnotation], using [Variance.inout] as the initial variance.
  void checkInOut(TypeAnnotation? typeAnnotation) =>
      check(Variance.inout, typeAnnotation);

  /// Hook, used to perform specialized checks on named types.
  ///
  /// The purpose of [VarianceChecker] is to be subclassed. The
  /// subclass implements this method to perform whatever check is needed
  /// for each named type. This hook will be invoked on each named type,
  /// providing the [variance] of the position where it occurs, the
  /// [staticType] which is the meaning of the given type annotation,
  /// and the [typeAnnotation] itself.
  void checkNamedType(
    Variance variance,
    DartType staticType,
    TypeAnnotation typeAnnotation,
  );

  /// Check [typeAnnotation], using [Variance.out] as the initial variance.
  void checkOut(TypeAnnotation? typeAnnotation) =>
      check(Variance.out, typeAnnotation);
}
