// 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/ast/syntactic_entity.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/utilities/extensions/version.dart';
import 'package:pub_semver/pub_semver.dart';

/// A visitor that finds code that assumes a later version of the SDK than the
/// minimum version required by the SDK constraints in `pubspec.yaml`.
class SdkConstraintVerifier extends RecursiveAstVisitor<void> {
  /// The error reporter to be used to report errors.
  final ErrorReporter _errorReporter;

  /// The element representing the library containing the unit to be verified.
  final LibraryElement _containingLibrary;

  /// The typ provider used to access SDK types.
  final TypeProvider _typeProvider;

  /// The version constraint for the SDK.
  final VersionConstraint _versionConstraint;

  /// A cached flag indicating whether references to the triple-shift features
  /// need to be checked. Use [checkTripleShift] to access this field.
  bool? _checkTripleShift;

  /// Initialize a newly created verifier to use the given [_errorReporter] to
  /// report errors.
  SdkConstraintVerifier(this._errorReporter, this._containingLibrary,
      this._typeProvider, this._versionConstraint);

  /// Return a range covering every version up to, but not including, 2.14.0.
  VersionRange get before_2_14_0 =>
      VersionRange(max: Version.parse('2.14.0'), includeMax: false);

  /// Return a range covering every version up to, but not including, 2.1.0.
  VersionRange get before_2_1_0 =>
      VersionRange(max: Version.parse('2.1.0'), includeMax: false);

  /// Return a range covering every version up to, but not including, 2.2.0.
  VersionRange get before_2_2_0 =>
      VersionRange(max: Version.parse('2.2.0'), includeMax: false);

  /// Return a range covering every version up to, but not including, 2.2.2.
  VersionRange get before_2_2_2 =>
      VersionRange(max: Version.parse('2.2.2'), includeMax: false);

  /// Return a range covering every version up to, but not including, 2.5.0.
  VersionRange get before_2_5_0 =>
      VersionRange(max: Version.parse('2.5.0'), includeMax: false);

  /// Return a range covering every version up to, but not including, 2.6.0.
  VersionRange get before_2_6_0 =>
      VersionRange(max: Version.parse('2.6.0'), includeMax: false);

  /// Return `true` if references to the non-nullable features need to be
  /// checked.
  bool get checkNnbd => !_containingLibrary.isNonNullableByDefault;

  /// Return `true` if references to the constant-update-2018 features need to
  /// be checked.
  bool get checkTripleShift => _checkTripleShift ??=
      !before_2_14_0.intersect(_versionConstraint).isEmpty;

  @override
  void visitArgumentList(ArgumentList node) {
    // Check (optional) positional arguments.
    // Named arguments are checked in [NamedExpression].
    for (final argument in node.arguments) {
      if (argument is! NamedExpression) {
        final parameter = argument.staticParameterElement;
        _checkSinceSdkVersion(parameter, node, errorEntity: argument);
      }
    }

    super.visitArgumentList(node);
  }

  @override
  void visitAssignmentExpression(AssignmentExpression node) {
    _checkSinceSdkVersion(node.readElement, node);
    _checkSinceSdkVersion(node.writeElement, node);
    super.visitAssignmentExpression(node);
  }

  @override
  void visitBinaryExpression(BinaryExpression node) {
    if (checkTripleShift) {
      TokenType operatorType = node.operator.type;
      if (operatorType == TokenType.GT_GT_GT) {
        _errorReporter.reportErrorForToken(
            WarningCode.SDK_VERSION_GT_GT_GT_OPERATOR, node.operator);
      }
    }
    super.visitBinaryExpression(node);
  }

  @override
  void visitConstructorName(ConstructorName node) {
    _checkSinceSdkVersion(node.staticElement, node);
    super.visitConstructorName(node);
  }

  @override
  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
    _checkSinceSdkVersion(node.staticElement, node);
    super.visitFunctionExpressionInvocation(node);
  }

  @override
  void visitHideCombinator(HideCombinator node) {
    // Don't flag references to either `Future` or `Stream` within a combinator.
  }

  @override
  void visitIndexExpression(IndexExpression node) {
    _checkSinceSdkVersion(node.staticElement, node);
    super.visitIndexExpression(node);
  }

  @override
  void visitMethodDeclaration(MethodDeclaration node) {
    if (checkTripleShift && node.isOperator && node.name.lexeme == '>>>') {
      _errorReporter.reportErrorForToken(
          WarningCode.SDK_VERSION_GT_GT_GT_OPERATOR, node.name);
    }
    super.visitMethodDeclaration(node);
  }

  @override
  void visitMethodInvocation(MethodInvocation node) {
    _checkSinceSdkVersion(node.methodName.staticElement, node);
    super.visitMethodInvocation(node);
  }

  @override
  void visitNamedType(NamedType node) {
    if (checkNnbd && node.element == _typeProvider.neverType.element) {
      _errorReporter.reportErrorForNode(WarningCode.SDK_VERSION_NEVER, node);
    }

    _checkSinceSdkVersion(node.element, node);
    super.visitNamedType(node);
  }

  @override
  void visitPrefixedIdentifier(PrefixedIdentifier node) {
    _checkSinceSdkVersion(node.staticElement, node);
    super.visitPrefixedIdentifier(node);
  }

  @override
  void visitPropertyAccess(PropertyAccess node) {
    _checkSinceSdkVersion(node.propertyName.staticElement, node);
    super.visitPropertyAccess(node);
  }

  @override
  void visitShowCombinator(ShowCombinator node) {
    // Don't flag references to either `Future` or `Stream` within a combinator.
  }

  @override
  void visitSimpleIdentifier(SimpleIdentifier node) {
    if (node.inDeclarationContext()) {
      return;
    }
    _checkSinceSdkVersion(node.staticElement, node);
  }

  void _checkSinceSdkVersion(
    Element? element,
    AstNode target, {
    SyntacticEntity? errorEntity,
  }) {
    if (element != null) {
      final sinceSdkVersion = element.sinceSdkVersion;
      if (sinceSdkVersion != null) {
        if (!_versionConstraint.requiresAtLeast(sinceSdkVersion)) {
          if (errorEntity == null) {
            if (!_shouldReportEnumIndex(target, element)) {
              return;
            }
            if (target is AssignmentExpression) {
              target = target.leftHandSide;
            }
            if (target is ConstructorName) {
              errorEntity = target.name?.token ?? target.type.name2;
            } else if (target is ExtensionOverride) {
              errorEntity = target.name;
            } else if (target is FunctionExpressionInvocation) {
              errorEntity = target.argumentList;
            } else if (target is IndexExpression) {
              errorEntity = target.leftBracket;
            } else if (target is MethodInvocation) {
              errorEntity = target.methodName;
            } else if (target is NamedType) {
              errorEntity = target.name2;
            } else if (target is PrefixedIdentifier) {
              errorEntity = target.identifier;
            } else if (target is PropertyAccess) {
              errorEntity = target.propertyName;
            } else if (target is SimpleIdentifier) {
              errorEntity = target;
            } else {
              throw UnimplementedError('(${target.runtimeType}) $target');
            }
          }
          _errorReporter.reportErrorForOffset(
            WarningCode.SDK_VERSION_SINCE,
            errorEntity.offset,
            errorEntity.length,
            [
              sinceSdkVersion.toString(),
              _versionConstraint.toString(),
            ],
          );
        }
      }
    }
  }

  /// Returns `false` if [element] is the `index` property, and the target
  /// of [node] is exactly the `Enum` class from `dart:core`. We have already
  /// checked that the property is not available to the enclosing package.
  ///
  /// Returns `true` if [element] is something else, or if the target is a
  /// concrete enum. The `index` was always available for concrete enums,
  /// but there was no common `Enum` supertype for all enums.
  static bool _shouldReportEnumIndex(AstNode node, Element element) {
    if (element is PropertyAccessorElement && element.name == 'index') {
      DartType? targetType;
      if (node is PrefixedIdentifier) {
        targetType = node.prefix.staticType;
      } else if (node is PropertyAccess) {
        targetType = node.realTarget.staticType;
      }
      if (targetType != null) {
        final targetElement = targetType.element;
        return targetElement is ClassElement && targetElement.isDartCoreEnum;
      }
      return false;
    } else {
      return true;
    }
  }
}
