// 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.futureOrType(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);
  }
}
