// Copyright (c) 2020, 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:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';

class AddAsync extends CorrectionProducer {
  /// A flag indicating whether this producer is producing a fix in the case
  /// where a function is missing a return at the end.
  final bool isForMissingReturn;

  /// Initialize a newly created producer.
  AddAsync(this.isForMissingReturn);

  @override
  FixKind get fixKind => DartFixKind.ADD_ASYNC;

  @override
  Future<void> compute(ChangeBuilder builder) async {
    if (isForMissingReturn) {
      var parent = node.parent;
      FunctionBody? body;
      DartType? returnType;
      if (parent is FunctionDeclaration) {
        body = parent.functionExpression.body;
        returnType = parent.declaredElement!.returnType;
      } else if (parent is MethodDeclaration) {
        body = parent.body;
        returnType = parent.declaredElement!.returnType;
      }
      if (body == null || returnType == null) {
        return;
      }
      if (_isFutureVoid(returnType) && _hasNoReturns(body)) {
        var final_body = body;
        await builder.addDartFileEdit(file, (builder) {
          builder.addSimpleInsertion(final_body.offset, 'async ');
        });
      }
    } else {
      var body = node.thisOrAncestorOfType<FunctionBody>();
      if (body != null && body.keyword == null) {
        final typeProvider = this.typeProvider;
        await builder.addDartFileEdit(file, (builder) {
          builder.convertFunctionFromSyncToAsync(body, typeProvider);
        });
      }
    }
  }

  /// Return `true` if there are no return statements in the given function
  /// [body].
  bool _hasNoReturns(FunctionBody body) {
    var finder = _ReturnFinder();
    body.accept(finder);
    return !finder.foundReturn;
  }

  /// Return `true` if the [type] is `Future<void>`.
  bool _isFutureVoid(DartType type) {
    if (type is InterfaceType && type.isDartAsyncFuture) {
      return type.typeArguments[0].isVoid;
    }
    return false;
  }

  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
  static AddAsync missingReturn() => AddAsync(true);

  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
  static AddAsync newInstance() => AddAsync(false);
}

/// An AST visitor used to find return statements in function bodies.
class _ReturnFinder extends RecursiveAstVisitor<void> {
  /// A flag indicating whether a return statement was visited.
  bool foundReturn = false;

  /// Initialize a newly created visitor.
  _ReturnFinder();

  @override
  void visitFunctionExpression(FunctionExpression node) {
    // Return statements within closures aren't counted.
  }

  @override
  void visitReturnStatement(ReturnStatement node) {
    foundReturn = true;
  }
}
