// 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/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/error/listener.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/resolver.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 constant-update-2018
  /// features need to be checked. Use [checkConstantUpdate2018] to access this
  /// field.
  bool _checkConstantUpdate2018;

  /// A cached flag indicating whether references to Future and Stream need to
  /// be checked. Use [checkFutureAndStream] to access this field.
  bool _checkFutureAndStream;

  /// A cached flag indicating whether references to set literals need to
  /// be checked. Use [checkSetLiterals] to access this field.
  bool _checkSetLiterals;

  /// A flag indicating whether we are visiting code inside a set literal. Used
  /// to prevent over-reporting uses of set literals.
  bool _inSetLiteral = false;

  /// A cached flag indicating whether references to the ui-as-code features
  /// need to be checked. Use [checkUiAsCode] to access this field.
  bool _checkUiAsCode;

  /// A flag indicating whether we are visiting code inside one of the
  /// ui-as-code features. Used to prevent over-reporting uses of these
  /// features.
  bool _inUiAsCode = false;

  /// 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.1.0.
  VersionRange get before_2_1_0 =>
      new 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 =>
      new 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 =>
      new VersionRange(max: Version.parse('2.2.2'), includeMax: false);

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

  /// Return `true` if references to Future and Stream need to be checked.
  bool get checkFutureAndStream => _checkFutureAndStream ??=
      !before_2_1_0.intersect(_versionConstraint).isEmpty;

  /// Return `true` if references to the non-nullable features need to be
  /// checked.
  // TODO(brianwilkerson) Implement this as a version check when a version has
  //  been selected.
  bool get checkNnbd => true;

  /// Return `true` if references to set literals need to be checked.
  bool get checkSetLiterals =>
      _checkSetLiterals ??= !before_2_2_0.intersect(_versionConstraint).isEmpty;

  /// Return `true` if references to the ui-as-code features (control flow and
  /// spread collections) need to be checked.
  bool get checkUiAsCode =>
      _checkUiAsCode ??= !before_2_2_2.intersect(_versionConstraint).isEmpty;

  @override
  void visitAsExpression(AsExpression node) {
    if (checkConstantUpdate2018 &&
        (node as AsExpressionImpl).inConstantContext) {
      _errorReporter.reportErrorForNode(
          HintCode.SDK_VERSION_AS_EXPRESSION_IN_CONST_CONTEXT, node);
    }
    super.visitAsExpression(node);
  }

  @override
  void visitBinaryExpression(BinaryExpression node) {
    if (checkConstantUpdate2018) {
      TokenType operatorType = node.operator.type;
      if (operatorType == TokenType.GT_GT_GT) {
        _errorReporter.reportErrorForToken(
            HintCode.SDK_VERSION_GT_GT_GT_OPERATOR, node.operator);
      } else if ((operatorType == TokenType.AMPERSAND ||
              operatorType == TokenType.BAR ||
              operatorType == TokenType.CARET) &&
          (node as BinaryExpressionImpl).inConstantContext) {
        if (node.leftOperand.staticType.isDartCoreBool) {
          _errorReporter.reportErrorForToken(HintCode.SDK_VERSION_BOOL_OPERATOR,
              node.operator, [node.operator.lexeme]);
        }
      } else if (operatorType == TokenType.EQ_EQ &&
          (node as BinaryExpressionImpl).inConstantContext) {
        bool primitive(Expression node) {
          DartType type = node.staticType;
          return type.isDartCoreBool ||
              type.isDartCoreDouble ||
              type.isDartCoreInt ||
              type.isDartCoreNull ||
              type.isDartCoreString;
        }

        if (!primitive(node.leftOperand) || !primitive(node.rightOperand)) {
          _errorReporter.reportErrorForToken(
              HintCode.SDK_VERSION_EQ_EQ_OPERATOR_IN_CONST_CONTEXT,
              node.operator);
        }
      }
    }
    super.visitBinaryExpression(node);
  }

  @override
  void visitForElement(ForElement node) {
    _validateUiAsCode(node);
    bool wasInUiAsCode = _inUiAsCode;
    _inUiAsCode = true;
    super.visitForElement(node);
    _inUiAsCode = wasInUiAsCode;
  }

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

  @override
  void visitIfElement(IfElement node) {
    _validateUiAsCode(node);
    bool wasInUiAsCode = _inUiAsCode;
    _inUiAsCode = true;
    super.visitIfElement(node);
    _inUiAsCode = wasInUiAsCode;
  }

  @override
  void visitIsExpression(IsExpression node) {
    if (checkConstantUpdate2018 &&
        (node as IsExpressionImpl).inConstantContext) {
      _errorReporter.reportErrorForNode(
          HintCode.SDK_VERSION_IS_EXPRESSION_IN_CONST_CONTEXT, node);
    }
    super.visitIsExpression(node);
  }

  @override
  void visitMethodDeclaration(MethodDeclaration node) {
    if (checkConstantUpdate2018 && node.isOperator && node.name.name == '>>>') {
      _errorReporter.reportErrorForNode(
          HintCode.SDK_VERSION_GT_GT_GT_OPERATOR, node.name);
    }
    super.visitMethodDeclaration(node);
  }

  @override
  void visitSetOrMapLiteral(SetOrMapLiteral node) {
    if (node.isSet && checkSetLiterals && !_inSetLiteral) {
      _errorReporter.reportErrorForNode(HintCode.SDK_VERSION_SET_LITERAL, node);
    }
    bool wasInSetLiteral = _inSetLiteral;
    _inSetLiteral = true;
    super.visitSetOrMapLiteral(node);
    _inSetLiteral = wasInSetLiteral;
  }

  @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;
    }
    Element element = node.staticElement;
    if (checkFutureAndStream &&
        (element == _typeProvider.futureType.element ||
            element == _typeProvider.streamType.element)) {
      for (LibraryElement importedLibrary
          in _containingLibrary.importedLibraries) {
        if (!importedLibrary.isDartCore) {
          Namespace namespace = importedLibrary.exportNamespace;
          if (namespace != null && namespace.get(element.name) != null) {
            return;
          }
        }
      }
      _errorReporter.reportErrorForNode(
          HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE, node, [element.name]);
    } else if (checkNnbd && element == _typeProvider.neverType.element) {
      _errorReporter.reportErrorForNode(HintCode.SDK_VERSION_NEVER, node);
    }
  }

  @override
  void visitSpreadElement(SpreadElement node) {
    _validateUiAsCode(node);
    bool wasInUiAsCode = _inUiAsCode;
    _inUiAsCode = true;
    super.visitSpreadElement(node);
    _inUiAsCode = wasInUiAsCode;
  }

  /// Given that the [node] is only valid when the ui-as-code feature is
  /// enabled, check that the code will not be executed with a version of the
  /// SDK that does not support the feature.
  void _validateUiAsCode(AstNode node) {
    if (checkUiAsCode && !_inUiAsCode) {
      _errorReporter.reportErrorForNode(HintCode.SDK_VERSION_UI_AS_CODE, node);
    }
  }
}
