// Copyright (c) 2017, 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/protocol_server.dart' hide Element;
import 'package:analysis_server/src/services/correction/util.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/dart/element/type_system.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';
import 'package:collection/collection.dart';

/// An enumeration of possible postfix completion kinds.
class DartPostfixCompletion {
  static const NO_TEMPLATE =
      PostfixCompletionKind('', 'no change', _false, _null);

  static const List<PostfixCompletionKind> ALL_TEMPLATES = [
    PostfixCompletionKind('assert', 'expr.assert -> assert(expr);',
        isAssertContext, expandAssert),
    PostfixCompletionKind(
        'fori',
        'limit.fori -> for(var i = 0; i < limit; i++) {}',
        isIntContext,
        expandFori),
    PostfixCompletionKind('for', 'values.for -> for(var value in values) {}',
        isIterableContext, expandFor),
    PostfixCompletionKind('iter', 'values.iter -> for(var value in values) {}',
        isIterableContext, expandFor),
    PostfixCompletionKind(
        'not', 'bool.not -> !bool', isBoolContext, expandNegate),
    PostfixCompletionKind('!', 'bool! -> !bool', isBoolContext, expandNegate),
    PostfixCompletionKind(
        'else', 'bool.else -> if (!bool) {}', isBoolContext, expandElse),
    PostfixCompletionKind(
        'if', 'bool.if -> if (bool) {}', isBoolContext, expandIf),
    PostfixCompletionKind('nn', 'expr.nn -> if (expr != null) {}',
        isObjectContext, expandNotNull),
    PostfixCompletionKind('notnull', 'expr.notnull -> if (expr != null) {}',
        isObjectContext, expandNotNull),
    PostfixCompletionKind('null', 'expr.null -> if (expr == null) {}',
        isObjectContext, expandNull),
    PostfixCompletionKind(
        'par', 'expr.par -> (expr)', isObjectContext, expandParen),
    PostfixCompletionKind(
        'return', 'expr.return -> return expr', isObjectContext, expandReturn),
    PostfixCompletionKind('switch', 'expr.switch -> switch (expr) {}',
        isSwitchContext, expandSwitch),
    PostfixCompletionKind('try', 'stmt.try -> try {stmt} catch (e,s) {}',
        isStatementContext, expandTry),
    PostfixCompletionKind(
        'tryon',
        'stmt.try -> try {stmt} on Exception catch (e,s) {}',
        isStatementContext,
        expandTryon),
    PostfixCompletionKind(
        'while', 'expr.while -> while (expr) {}', isBoolContext, expandWhile),
  ];

  static Future<PostfixCompletion?> expandAssert(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expand(kind, processor.findAssertExpression, (expr) {
      return 'assert(${processor.utils.getNodeText(expr)});';
    }, withBraces: false);
  }

  static Future<PostfixCompletion?> expandElse(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expand(kind, processor.findBoolExpression,
        (expr) => 'if (${processor.makeNegatedBoolExpr(expr)})');
  }

  static Future<PostfixCompletion?> expandFor(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expand(kind, processor.findIterableExpression, (expr) {
      var value = processor.newVariable('value');
      return 'for (var $value in ${processor.utils.getNodeText(expr)})';
    });
  }

  static Future<PostfixCompletion?> expandFori(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expand(kind, processor.findIntExpression, (expr) {
      var index = processor.newVariable('i');
      return 'for (int $index = 0; $index < ${processor.utils.getNodeText(expr)}; $index++)';
    });
  }

  static Future<PostfixCompletion?> expandIf(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expand(kind, processor.findBoolExpression,
        (expr) => 'if (${processor.utils.getNodeText(expr)})');
  }

  static Future<PostfixCompletion?> expandNegate(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expand(kind, processor.findBoolExpression,
        (expr) => processor.makeNegatedBoolExpr(expr),
        withBraces: false);
  }

  static Future<PostfixCompletion?> expandNotNull(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expand(kind, processor.findObjectExpression, (expr) {
      return expr is NullLiteral
          ? 'if (false)'
          : 'if (${processor.utils.getNodeText(expr)} != null)';
    });
  }

  static Future<PostfixCompletion?> expandNull(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expand(kind, processor.findObjectExpression, (expr) {
      return expr is NullLiteral
          ? 'if (true)'
          : 'if (${processor.utils.getNodeText(expr)} == null)';
    });
  }

  static Future<PostfixCompletion?> expandParen(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expand(kind, processor.findObjectExpression,
        (expr) => '(${processor.utils.getNodeText(expr)})',
        withBraces: false);
  }

  static Future<PostfixCompletion?> expandReturn(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expand(kind, processor.findObjectExpression,
        (expr) => 'return ${processor.utils.getNodeText(expr)};',
        withBraces: false);
  }

  static Future<PostfixCompletion?> expandSwitch(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expand(kind, processor.findObjectExpression,
        (expr) => 'switch (${processor.utils.getNodeText(expr)})');
  }

  static Future<PostfixCompletion?> expandTry(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expandTry(kind, processor.findStatement, withOn: false);
  }

  static Future<PostfixCompletion?> expandTryon(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expandTry(kind, processor.findStatement, withOn: true);
  }

  static Future<PostfixCompletion?> expandWhile(
      PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
    return processor.expand(kind, processor.findBoolExpression,
        (expr) => 'while (${processor.utils.getNodeText(expr)})');
  }

  static PostfixCompletionKind? forKey(String key) =>
      ALL_TEMPLATES.firstWhereOrNull((kind) => kind.key == key);

  static bool isAssertContext(PostfixCompletionProcessor processor) {
    return processor.findAssertExpression() != null;
  }

  static bool isBoolContext(PostfixCompletionProcessor processor) {
    return processor.findBoolExpression() != null;
  }

  static bool isIntContext(PostfixCompletionProcessor processor) {
    return processor.findIntExpression() != null;
  }

  static bool isIterableContext(PostfixCompletionProcessor processor) {
    return processor.findIterableExpression() != null;
  }

  static bool isObjectContext(PostfixCompletionProcessor processor) {
    return processor.findObjectExpression() != null;
  }

  static bool isStatementContext(PostfixCompletionProcessor processor) {
    return processor.findStatement() != null;
  }

  static bool isSwitchContext(PostfixCompletionProcessor processor) {
    return processor.findObjectExpression() != null;
  }

  static bool _false(_) => false;

  static Future<PostfixCompletion?> _null(_, __) async => null;
}

/// A description of a postfix completion.
///
/// Clients may not extend, implement or mix-in this class.
class PostfixCompletion {
  /// A description of the assist being proposed.
  final PostfixCompletionKind kind;

  /// The change to be made in order to apply the assist.
  final SourceChange change;

  /// Initialize a newly created completion to have the given [kind] and
  /// [change].
  PostfixCompletion(this.kind, this.change);
}

/// The context for computing a postfix completion.
class PostfixCompletionContext {
  final ResolvedUnitResult resolveResult;
  final int selectionOffset;
  final String key;

  PostfixCompletionContext(this.resolveResult, this.selectionOffset, this.key);
}

/// A description of a template for postfix completion. Instances are intended
/// to hold the functions required to determine applicability and expand the
/// template, in addition to its name and simple example. The example is shown
/// (in IntelliJ) in a code-completion menu, so must be quite short.
///
/// Clients may not extend, implement or mix-in this class.
class PostfixCompletionKind {
  final String name, example;
  final bool Function(PostfixCompletionProcessor) selector;
  final Future<PostfixCompletion?> Function(
      PostfixCompletionProcessor, PostfixCompletionKind) computer;

  const PostfixCompletionKind(
      this.name, this.example, this.selector, this.computer);

  String get key => name == '!' ? name : '.$name';

  String get message => 'Expand $key';

  @override
  String toString() => name;
}

/// The computer for Dart postfix completions.
class PostfixCompletionProcessor {
  static final NO_COMPLETION = PostfixCompletion(
      DartPostfixCompletion.NO_TEMPLATE, SourceChange('', edits: []));

  final PostfixCompletionContext completionContext;
  final CorrectionUtils utils;
  AstNode? node;
  PostfixCompletion? completion;
  SourceChange change = SourceChange('postfix-completion');
  final Map<String, LinkedEditGroup> linkedPositionGroups = {};
  Position? exitPosition;

  PostfixCompletionProcessor(this.completionContext)
      : utils = CorrectionUtils(completionContext.resolveResult);

  String get eol => utils.endOfLine;

  String get file => completionContext.resolveResult.path;

  String get key => completionContext.key;

  LineInfo get lineInfo => completionContext.resolveResult.lineInfo;

  int get selectionOffset => completionContext.selectionOffset;

  AnalysisSession get session => completionContext.resolveResult.session;

  TypeProvider get typeProvider => completionContext.resolveResult.typeProvider;

  TypeSystem get typeSystem => completionContext.resolveResult.typeSystem;

  Future<PostfixCompletion> compute() async {
    node = _selectedNode();
    if (node == null) {
      return NO_COMPLETION;
    }
    var completer = DartPostfixCompletion.forKey(key);
    if (completer == null) {
      return NO_COMPLETION;
    }
    return await completer.computer(this, completer) ?? NO_COMPLETION;
  }

  Future<PostfixCompletion?> expand(PostfixCompletionKind kind,
      Expression? Function() contexter, String Function(Expression) sourcer,
      {bool withBraces = true}) async {
    var expr = contexter();
    if (expr == null) {
      return null;
    }

    var changeBuilder = ChangeBuilder(session: session);
    await changeBuilder.addDartFileEdit(file, (builder) {
      builder.addReplacement(range.node(expr), (builder) {
        var newSrc = sourcer(expr);
        builder.write(newSrc);
        if (withBraces) {
          builder.write(' {');
          builder.write(eol);
          var indent = utils.getNodePrefix(expr);
          builder.write(indent);
          builder.write(utils.getIndent(1));
          builder.selectHere();
          builder.write(eol);
          builder.write(indent);
          builder.write('}');
        } else {
          builder.selectHere();
        }
      });
    });
    _setCompletionFromBuilder(changeBuilder, kind);
    return completion;
  }

  Future<PostfixCompletion?> expandTry(
      PostfixCompletionKind kind, Statement? Function() contexter,
      {bool withOn = false}) async {
    var stmt = contexter();
    if (stmt == null) {
      return null;
    }
    var changeBuilder = ChangeBuilder(session: session);
    await changeBuilder.addDartFileEdit(file, (builder) {
      // Embed the full line(s) of the statement in the try block.
      var startLine = lineInfo.getLocation(stmt.offset).lineNumber - 1;
      var endLine = lineInfo.getLocation(stmt.end).lineNumber - 1;
      if (stmt is ExpressionStatement) {
        var semicolon = stmt.semicolon;
        if (semicolon != null && !semicolon.isSynthetic) {
          endLine += 1;
        }
      }
      var startOffset = lineInfo.getOffsetOfLine(startLine);
      var endOffset = lineInfo.getOffsetOfLine(endLine);
      var src = utils.getText(startOffset, endOffset - startOffset);
      var indent = utils.getLinePrefix(stmt.offset);
      builder.addReplacement(range.startOffsetEndOffset(startOffset, endOffset),
          (builder) {
        builder.write(indent);
        builder.write('try {');
        builder.write(eol);
        builder.write(src.replaceAll(RegExp('^$indent', multiLine: true),
            '$indent${utils.getIndent(1)}'));
        builder.selectHere();
        builder.write(indent);
        builder.write('}');
        if (withOn) {
          builder.write(' on ');
          builder.addSimpleLinkedEdit('NAME', nameOfExceptionThrownBy(stmt));
        }
        builder.write(' catch (e, s) {');
        builder.write(eol);
        builder.write(indent);
        builder.write(utils.getIndent(1));
        builder.write('print(s);');
        builder.write(eol);
        builder.write(indent);
        builder.write('}');
        builder.write(eol);
      });
    });
    _setCompletionFromBuilder(changeBuilder, kind);
    return completion;
  }

  Expression? findAssertExpression() {
    final node = this.node;
    if (node is Expression) {
      var boolExpr = _findOuterExpression(node, typeProvider.boolType);
      if (boolExpr == null) {
        return null;
      }
      var parent = boolExpr.parent;
      var grandParent = parent?.parent;
      if (parent is ExpressionFunctionBody &&
          grandParent is FunctionExpression) {
        var type = grandParent.staticType;
        if (type is! FunctionType) {
          return boolExpr;
        }
        if (type.returnType == typeProvider.boolType) {
          return grandParent;
        }
      }
      if (boolExpr.staticType == typeProvider.boolType) {
        return boolExpr;
      }
    }
    return null;
  }

  Expression? findBoolExpression() =>
      _findOuterExpression(node, typeProvider.boolType);

  Expression? findIntExpression() =>
      _findOuterExpression(node, typeProvider.intType);

  Expression? findIterableExpression() =>
      _findOuterExpression(node, typeProvider.iterableDynamicType);

  Expression? findObjectExpression() =>
      _findOuterExpression(node, typeProvider.objectType);

  Statement? findStatement() {
    var astNode = node;
    while (astNode != null) {
      if (astNode is Statement && astNode is! Block) {
        // Disallow control-flow statements.
        if (astNode is DoStatement ||
            astNode is IfStatement ||
            astNode is ForStatement ||
            astNode is SwitchStatement ||
            astNode is TryStatement ||
            astNode is WhileStatement) {
          return null;
        }
        return astNode;
      }
      astNode = astNode.parent;
    }
    return null;
  }

  Future<bool> isApplicable() async {
    node = _selectedNode();
    if (node == null) {
      return false;
    }
    var completer = DartPostfixCompletion.forKey(key);
    if (completer == null) {
      return false;
    }
    return completer.selector(this);
  }

  String makeNegatedBoolExpr(Expression expr) {
    var originalSrc = utils.getNodeText(expr);
    var newSrc = utils.invertCondition(expr);
    if (newSrc != originalSrc) {
      return newSrc;
    } else {
      return '!${utils.getNodeText(expr)}';
    }
  }

  String nameOfExceptionThrownBy(AstNode astNode) {
    if (astNode is ExpressionStatement) {
      astNode = astNode.expression;
    }
    if (astNode is ThrowExpression) {
      var expr = astNode;
      var type = expr.expression.staticType;
      if (type is! TypeImpl) {
        return 'Exception';
      }

      // Only print nullability for non-legacy types in non-legacy libraries.
      var showNullability = type.nullabilitySuffix != NullabilitySuffix.star &&
          (astNode.root as CompilationUnit)
              .declaredElement!
              .library
              .isNonNullableByDefault;

      // Can't catch nullable types, strip `?`s now that we've checked for `*`s.
      return type
          .withNullability(NullabilitySuffix.none)
          .getDisplayString(withNullability: showNullability);
    }
    return 'Exception';
  }

  String newVariable(String base) {
    var name = base;
    var i = 1;
    var vars = utils.findPossibleLocalVariableConflicts(selectionOffset);
    while (vars.contains(name)) {
      name = '$base${i++}';
    }
    return name;
  }

  Expression? _findOuterExpression(AstNode? start, InterfaceType builtInType) {
    if (start is SimpleIdentifier && start.staticElement is PrefixElement) {
      return null;
    }

    AstNode? parent;
    if (start is Expression) {
      parent = start;
    } else if (start is ArgumentList) {
      parent = start.parent;
    }
    if (parent == null) {
      return null;
    }

    var list = <Expression>[];
    while (parent is Expression) {
      list.add(parent);
      parent = parent.parent;
    }

    var expr = list.firstWhereOrNull((expr) {
      var type = expr.staticType;
      if (type == null) return false;
      return typeSystem.isSubtypeOf(type, builtInType);
    });
    var exprParent = expr?.parent;
    if (expr is SimpleIdentifier && exprParent is PropertyAccess) {
      expr = exprParent;
    }
    if (exprParent is CascadeExpression) {
      expr = exprParent;
    }
    return expr;
  }

  AstNode? _selectedNode({int? at}) => NodeLocator(at ?? selectionOffset)
      .searchWithin(completionContext.resolveResult.unit);

  void _setCompletionFromBuilder(
      ChangeBuilder builder, PostfixCompletionKind kind,
      [List? args]) {
    var change = builder.sourceChange;
    if (change.edits.isEmpty) {
      completion = null;
      return;
    }
    change.message = formatList(kind.message, args);
    completion = PostfixCompletion(kind, change);
  }
}
