// Copyright (c) 2022, 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/snippets/snippet_context.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/ast/token.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/source/source_range.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';

/// The information about a request for a list of snippets within a Dart file.
class DartSnippetRequest {
  /// The resolved unit for the file that snippets are being requested for.
  final ResolvedUnitResult unit;

  /// The path of the file snippets are being requested for.
  final String filePath;

  /// The offset within the source at which snippets are being
  /// requested for.
  final int offset;

  /// The context in which the snippet request is being made.
  late final SnippetContext context;

  /// The source range that represents the region of text that should be
  /// replaced if the snippet is selected.
  late final SourceRange replacementRange;

  DartSnippetRequest({
    required this.unit,
    required this.offset,
  }) : filePath = unit.path {
    final target = CompletionTarget.forOffset(unit.unit, offset);
    context = _getContext(target);
    replacementRange = target.computeReplacementRange(offset);
  }

  /// The analysis session that produced the elements of the request.
  AnalysisSession get analysisSession => unit.session;

  /// The resource provider associated with this request.
  ResourceProvider get resourceProvider => analysisSession.resourceProvider;

  static SnippetContext _getContext(CompletionTarget target) {
    final entity = target.entity;
    if (entity is Token) {
      final tokenType = (entity.beforeSynthetic ?? entity).type;

      if (tokenType == TokenType.MULTI_LINE_COMMENT ||
          tokenType == TokenType.SINGLE_LINE_COMMENT) {
        return SnippetContext.inComment;
      }

      if (tokenType == TokenType.STRING ||
          tokenType == TokenType.STRING_INTERPOLATION_EXPRESSION ||
          tokenType == TokenType.STRING_INTERPOLATION_IDENTIFIER) {
        return SnippetContext.inString;
      }
    }

    AstNode? node = target.containingNode;
    while (node != null) {
      if (node is Comment) {
        return SnippetContext.inComment;
      }

      if (node is StringLiteral) {
        return SnippetContext.inString;
      }

      if (node is Block) {
        return SnippetContext.inBlock;
      }

      if (node is Statement || node is Expression || node is Annotation) {
        return SnippetContext.inExpressionOrStatement;
      }

      if (node is BlockFunctionBody) {
        return SnippetContext.inBlock;
      }

      if (node is ClassOrMixinDeclaration || node is ExtensionDeclaration) {
        return SnippetContext.inClass;
      }

      node = node.parent;
    }

    return SnippetContext.atTopLevel;
  }
}
