// 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 'dart:async';

import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/utilities/progress.dart';
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:dart_style/src/dart_formatter.dart';
import 'package:dart_style/src/exceptions.dart';
import 'package:dart_style/src/source_code.dart';

/// The handler for the `edit.formatIfEnabled` request.
class EditFormatIfEnabledHandler extends LegacyHandler {
  /// Initialize a newly created handler to be able to service requests for the
  /// [server].
  EditFormatIfEnabledHandler(AnalysisServer server, Request request,
      CancellationToken cancellationToken)
      : super(server, request, cancellationToken);

  /// Format the file at the given [filePath].
  ///
  /// Throws a [FileSystemException] if the file doesn't exist or can't be read.
  /// Throws a [FormatterException] if the code could not be formatted.
  List<SourceEdit> formatFile(String filePath) {
    // TODO(brianwilkerson) Move this to a superclass when `edit.format` is
    //  implemented by a handler class so the code can be shared.
    var resource = server.resourceProvider.getFile(filePath);
    var originalContent = resource.readAsStringSync();
    var code = SourceCode(originalContent, uri: null, isCompilationUnit: true);

    var formatter = DartFormatter();
    var formatResult = formatter.formatSource(code);
    var formattedContent = formatResult.text;

    var edits = <SourceEdit>[];
    if (formattedContent != originalContent) {
      // TODO(brianwilkerson) Replace full replacements with smaller, more
      //  targeted edits.
      var edit = SourceEdit(0, originalContent.length, formattedContent);
      edits.add(edit);
    }
    return edits;
  }

  @override
  Future<void> handle() async {
    var params = EditFormatIfEnabledParams.fromRequest(request);
    var collection = AnalysisContextCollectionImpl(
      includedPaths: params.directories,
      resourceProvider: server.resourceProvider,
      sdkPath: server.sdkPath,
    );
    var sourceFileEdits = <SourceFileEdit>[];
    for (var context in collection.contexts) {
      if (context.analysisOptions.codeStyleOptions.useFormatter) {
        _formatInContext(context, sourceFileEdits);
      }
    }
    sendResult(EditFormatIfEnabledResult(sourceFileEdits));
  }

  /// Format all of the files in the given [context], adding the edits to the
  /// list of [sourceFileEdits].
  void _formatInContext(DriverBasedAnalysisContext context,
      List<SourceFileEdit> sourceFileEdits) {
    for (var filePath in context.contextRoot.analyzedFiles()) {
      var pathContext = context.resourceProvider.pathContext;
      if (file_paths.isDart(pathContext, filePath)) {
        try {
          var sourceEdits = formatFile(filePath);
          if (sourceEdits.isNotEmpty) {
            sourceFileEdits
                .add(SourceFileEdit(filePath, 0, edits: sourceEdits));
          }
        } catch (exception) {
          // Ignore files that can't be formatted.
        }
      }
    }
  }
}
