// Copyright (c) 2021, 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/visitor.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/error/return_type_verifier.dart';
import 'package:analyzer/src/generated/error_verifier.dart';

/// Reports on invalid functions passed to [Future.catchError].
class CatchErrorVerifier {
  final ErrorReporter _errorReporter;

  final TypeProviderImpl _typeProvider;

  final TypeSystemImpl _typeSystem;

  final ReturnTypeVerifier _returnTypeVerifier;

  CatchErrorVerifier(this._errorReporter, this._typeProvider, this._typeSystem)
      : _returnTypeVerifier = ReturnTypeVerifier(
          typeProvider: _typeProvider,
          typeSystem: _typeSystem,
          errorReporter: _errorReporter,
        );

  void verifyMethodInvocation(MethodInvocation node) {
    var target = node.realTarget;
    if (target == null) {
      return;
    }
    var methodName = node.methodName;
    if (!(methodName.name == 'catchError' &&
        target.typeOrThrow.isDartAsyncFuture)) {
      return;
    }
    if (node.argumentList.arguments.isEmpty) {
      return;
    }
    var callback = node.argumentList.arguments.first;
    if (callback is NamedExpression) {
      // This implies that no positional arguments are passed.
      return;
    }
    var targetType = target.staticType as InterfaceType;
    var targetFutureType = targetType.typeArguments.first;
    var expectedReturnType = _typeProvider.futureOrType2(targetFutureType);
    if (callback is FunctionExpression) {
      // TODO(migration): should be FunctionType, not nullable
      var callbackType = callback.staticType as FunctionType;
      _checkOnErrorFunctionType(callback, callbackType, expectedReturnType);
      var catchErrorOnErrorExecutable = EnclosingExecutableContext(
          callback.declaredElement,
          isAsynchronous: true,
          catchErrorOnErrorReturnType: expectedReturnType);
      var returnStatementVerifier =
          _ReturnStatementVerifier(_returnTypeVerifier);
      _returnTypeVerifier.enclosingExecutable = catchErrorOnErrorExecutable;
      callback.body!.accept(returnStatementVerifier);
    } else {
      var callbackType = callback.staticType;
      if (callbackType is FunctionType) {
        _checkReturnType(expectedReturnType, callbackType.returnType, callback);
        _checkOnErrorFunctionType(callback, callbackType, expectedReturnType);
      } else {
        // If [callback] is not even a Function, then ErrorVerifier will have
        // reported this.
      }
    }
  }

  void _checkOnErrorFunctionType(Expression expression,
      FunctionType expressionType, DartType expectedFunctionReturnType) {
    void report() {
      _errorReporter.reportErrorForNode(
        HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE_CATCH_ERROR_ON_ERROR,
        expression,
        [expressionType, expectedFunctionReturnType],
      );
    }

    var parameters = expressionType.parameters;
    if (parameters.isEmpty) {
      return report();
    }
    var firstParameter = parameters.first;
    if (firstParameter.isNamed) {
      return report();
    } else {
      if (!_typeSystem.isSubtypeOf(
          _typeProvider.objectType, firstParameter.type)) {
        return report();
      }
    }
    if (parameters.length == 2) {
      var secondParameter = parameters[1];
      if (secondParameter.isNamed) {
        return report();
      } else {
        if (!_typeSystem.isSubtypeOf(
            _typeProvider.stackTraceType, secondParameter.type)) {
          return report();
        }
      }
    } else if (parameters.length > 2) {
      return report();
    }
  }

  void _checkReturnType(
      DartType expectedType, DartType functionReturnType, Expression callback) {
    if (!_typeSystem.isAssignableTo(functionReturnType, expectedType)) {
      _errorReporter.reportErrorForNode(
        HintCode.RETURN_TYPE_INVALID_FOR_CATCH_ERROR,
        callback,
        [functionReturnType, expectedType],
      );
    }
  }
}

/// Visits a function body, looking for return statements.
class _ReturnStatementVerifier extends RecursiveAstVisitor<void> {
  final ReturnTypeVerifier _returnTypeVerifier;

  _ReturnStatementVerifier(this._returnTypeVerifier);

  @override
  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
    _returnTypeVerifier.verifyExpressionFunctionBody(node);
    super.visitExpressionFunctionBody(node);
  }

  @override
  void visitFunctionExpression(FunctionExpression node) {
    // Do not visit within [node]. We have no interest in return statements
    // within.
  }
  @override
  void visitReturnStatement(ReturnStatement node) {
    _returnTypeVerifier.verifyReturnStatement(node);
    super.visitReturnStatement(node);
  }
}
