// 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/protocol_server.dart';
import 'package:analysis_server/src/provisional/completion/completion_core.dart';
import 'package:analysis_server/src/services/snippets/dart/dart_snippet_producers.dart';
import 'package:analysis_server/src/services/snippets/dart/flutter_snippet_producers.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/src/util/file_paths.dart' as file_paths;
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';

typedef SnippetProducerGenerator = SnippetProducer Function(DartSnippetRequest);

/// [DartSnippetManager] determines if a snippet request is Dart specific
/// and forwards those requests to all Snippet Producers that return `true` from
/// their `isValid()` method.
class DartSnippetManager {
  final producerGenerators =
      const <SnippetContext, List<SnippetProducerGenerator>>{
    SnippetContext.atTopLevel: [
      DartMainFunctionSnippetProducer.newInstance,
      FlutterStatefulWidgetSnippetProducer.newInstance,
      FlutterStatefulWidgetWithAnimationControllerSnippetProducer.newInstance,
      FlutterStatelessWidgetSnippetProducer.newInstance,
    ],
    SnippetContext.inBlock: [
      DartDoWhileLoopSnippetProducer.newInstance,
      DartForInLoopSnippetProducer.newInstance,
      DartForLoopSnippetProducer.newInstance,
      DartIfElseSnippetProducer.newInstance,
      DartIfSnippetProducer.newInstance,
      DartSwitchSnippetProducer.newInstance,
      DartTryCatchSnippetProducer.newInstance,
      DartWhileLoopSnippetProducer.newInstance,
    ],
  };

  Future<List<Snippet>> computeSnippets(
    DartSnippetRequest request,
  ) async {
    var pathContext = request.resourceProvider.pathContext;
    if (!file_paths.isDart(pathContext, request.filePath)) {
      return const [];
    }

    try {
      final snippets = <Snippet>[];
      final generators = producerGenerators[request.context];
      if (generators == null) {
        return snippets;
      }
      for (final generator in generators) {
        final producer = generator(request);
        if (await producer.isValid()) {
          snippets.add(await producer.compute());
        }
      }
      return snippets;
    } on InconsistentAnalysisException {
      // The state of the code being analyzed has changed, so results are likely
      // to be inconsistent. Just abort the operation.
      throw AbortCompletion();
    }
  }
}

/// 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;
  }
}

class Snippet {
  /// The text the user will type to use this snippet.
  final String prefix;

  /// The label/title of this snippet.
  final String label;

  /// A description of/documentation for the snippet.
  final String? documentation;

  /// The source changes to be made to insert this snippet.
  final SourceChange change;

  Snippet(
    this.prefix,
    this.label,
    this.documentation,
    this.change,
  );
}

/// The context in which a snippet request was made.
///
/// This is used to filter the available snippets (for example preventing
/// snippets that create classes showing up when inside an existing class or
/// function body).
enum SnippetContext {
  atTopLevel,
  inClass,
  inBlock,
  inExpressionOrStatement,
  inComment,
  inString,
}

abstract class SnippetProducer {
  final DartSnippetRequest request;

  SnippetProducer(this.request);

  Future<Snippet> compute();

  Future<bool> isValid() async {
    // File edit builders will not produce edits for files outside of the
    // analysis roots so we should not try to produce any snippets.
    final analysisContext = request.analysisSession.analysisContext;
    return analysisContext.contextRoot.isAnalyzed(request.filePath);
  }
}
