// 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/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
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_plugin/utilities/assist/assist.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';

class ShadowField extends CorrectionProducer {
  @override
  AssistKind get assistKind => DartAssistKind.SHADOW_FIELD;

  @override
  Future<void> compute(ChangeBuilder builder) async {
    if (node is! SimpleIdentifier) {
      return;
    }
    var element = (node as SimpleIdentifier).staticElement;
    if (element is! PropertyAccessorElement) {
      return;
    }
    var accessor = element as PropertyAccessorElement;
    if (!accessor.isGetter || accessor.enclosingElement is! ClassElement) {
      // TODO(brianwilkerson) Should we also require that the getter be synthetic?
      return;
    }
    var statement = _getStatement();
    if (statement == null) {
      return;
    }
    if (statement.parent is! Block) {
      // TODO(brianwilkerson) Support adding a block between the statement and
      //  its parent (where the parent will be something like a while or if
      //  statement). Also support the case where the parent is a case clause.
      return;
    }
    var enclosingBlock = statement.parent as Block;
    var finder = _ReferenceFinder(accessor.correspondingSetter);
    enclosingBlock.accept(finder);
    if (finder.hasSetterReference) {
      return;
    }
    var fieldName = accessor.name;
    var offset = statement.offset;
    var prefix = utils.getLinePrefix(offset);
    //
    // Build the change.
    //
    await builder.addDartFileEdit(file, (builder) {
      builder.addInsertion(offset, (builder) {
        // TODO(brianwilkerson) Conditionally write a type annotation instead of
        //  'var' when we're able to discover user preferences.
        builder.write('var ');
        builder.write(fieldName);
        builder.write(' = this.');
        builder.write(fieldName);
        builder.writeln(';');
        builder.write(prefix);
      });
      // TODO(brianwilkerson) Consider removing unnecessary casts and null
      //  checks that are no longer needed because promotion works. This would
      //  be dependent on whether enhanced promotion is supported in the library
      //  being edited.
    });
  }

  /// Return the statement immediately enclosing the [node] that would promote
  /// the type of the field if it were replaced by a local variable.
  Statement _getStatement() {
    var parent = node.parent;

    Statement enclosingIf(Expression expression) {
      var parent = expression.parent;
      while (parent is BinaryExpression) {
        var opType = (parent as BinaryExpression).operator.type;
        if (opType != TokenType.AMPERSAND_AMPERSAND) {
          break;
        }
        parent = parent.parent;
      }
      if (parent is IfStatement) {
        return parent;
      }
      return null;
    }

    if (parent is IsExpression && parent.expression == node) {
      return enclosingIf(parent);
    } else if (parent is BinaryExpression &&
        resolvedResult.libraryElement.isNonNullableByDefault) {
      var opType = parent.operator.type;
      if (opType == TokenType.EQ_EQ || opType == TokenType.BANG_EQ) {
        return enclosingIf(parent);
      }
    }
    return null;
  }

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

/// A utility that will find any references to a setter within an AST structure.
class _ReferenceFinder extends RecursiveAstVisitor<void> {
  /// The setter being searched for.
  final PropertyAccessorElement setter;

  /// A flag indicating whether a reference to the [setter] has been found.
  bool hasSetterReference = false;

  /// Initialize a newly created reference finder to find references to the
  /// given [setter].
  _ReferenceFinder(this.setter);

  @override
  void visitSimpleIdentifier(SimpleIdentifier node) {
    if (node.staticElement == setter) {
      hasSetterReference = true;
    }
  }
}
