// Copyright (c) 2018, 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'
    show CompletionSuggestion, RuntimeCompletionExpression, SourceEdit;
import 'package:analysis_server/src/services/completion/completion_core.dart';
import 'package:analysis_server/src/services/completion/completion_performance.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/file_system/overlay_file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';

class RuntimeCompletionComputer {
  final OverlayResourceProvider resourceProvider;
  final AnalysisDriver analysisDriver;

  final String code;
  final int offset;

  final String contextPath;
  final int contextOffset;

  RuntimeCompletionComputer(this.resourceProvider, this.analysisDriver,
      this.code, this.offset, this.contextPath, this.contextOffset);

  Future<RuntimeCompletionResult> compute() async {
    var contextResult = await analysisDriver.getResult2(contextPath);
    if (contextResult is! ResolvedUnitResult) {
      return RuntimeCompletionResult([], []);
    }

    var session = contextResult.session;

    const codeMarker = '__code_\_';

    // Insert the code being completed at the context offset.
    var changeBuilder = ChangeBuilder(session: session);
    var nextImportPrefixIndex = 0;
    await changeBuilder.addDartFileEdit(contextPath, (builder) {
      builder.addInsertion(contextOffset, (builder) {
        builder.writeln('{');

        // TODO(scheglov) Use variables.

        builder.write(codeMarker);
        builder.writeln(';');

        builder.writeln('}');
      });
    }, importPrefixGenerator: (uri) => '__prefix${nextImportPrefixIndex++}');

    // Compute the patched context file content.
    var targetCode = SourceEdit.applySequence(
      contextResult.content!,
      changeBuilder.sourceChange.edits[0].edits,
    );

    // Insert the code being completed.
    var targetOffset = targetCode.indexOf(codeMarker) + offset;
    targetCode = targetCode.replaceAll(codeMarker, code);

    // Update the context file content to include the code being completed.
    // Then resolve it, and restore the file to its initial state.
    var targetResult = await _withContextFileContent(targetCode, () async {
      return await analysisDriver.getResult2(contextPath);
    });
    if (targetResult is! ResolvedUnitResult) {
      return RuntimeCompletionResult([], []);
    }

    var contributor = DartCompletionManager(
        // dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(targetResult)
        );
    var request = CompletionRequestImpl(
      targetResult,
      targetOffset,
      CompletionPerformance(),
    );

    var suggestions = await request.performance.runRequestOperation(
      (performance) async {
        return await contributor.computeSuggestions(
          performance,
          request,
        );
      },
    );

    // Remove completions with synthetic import prefixes.
    suggestions.removeWhere((s) => s.completion.startsWith('__prefix'));

    // TODO(scheglov) Add support for expressions.
    var expressions = <RuntimeCompletionExpression>[];
    return RuntimeCompletionResult(expressions, suggestions);
  }

  Future<R> _withContextFileContent<R>(
      String newContent, Future<R> Function() f) async {
    if (resourceProvider.hasOverlay(contextPath)) {
      var contextFile = resourceProvider.getFile(contextPath);
      var prevOverlayContent = contextFile.readAsStringSync();
      var prevOverlayStamp = contextFile.modificationStamp;
      try {
        resourceProvider.setOverlay(
          contextPath,
          content: newContent,
          modificationStamp: 0,
        );
        analysisDriver.changeFile(contextPath);
        return await f();
      } finally {
        resourceProvider.setOverlay(
          contextPath,
          content: prevOverlayContent,
          modificationStamp: prevOverlayStamp,
        );
        analysisDriver.changeFile(contextPath);
      }
    } else {
      try {
        resourceProvider.setOverlay(
          contextPath,
          content: newContent,
          modificationStamp: 0,
        );
        analysisDriver.changeFile(contextPath);
        return await f();
      } finally {
        resourceProvider.removeOverlay(contextPath);
        analysisDriver.changeFile(contextPath);
      }
    }
  }
}

/// The result of performing runtime completion.
class RuntimeCompletionResult {
  final List<RuntimeCompletionExpression> expressions;
  final List<CompletionSuggestion> suggestions;

  RuntimeCompletionResult(this.expressions, this.suggestions);
}
