// 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/handler/legacy/legacy_handler.dart';
import 'package:analysis_server/src/protocol_server.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(
      super.server, super.request, super.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.
        }
      }
    }
  }
}
