// Copyright (c) 2021, 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/lsp_protocol/protocol.dart';
import 'package:analysis_server/src/computer/computer_selection_ranges.dart'
    hide SelectionRange;
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';

class SelectionRangeHandler
    extends MessageHandler<SelectionRangeParams, List<SelectionRange>?> {
  SelectionRangeHandler(super.server);
  @override
  Method get handlesMessage => Method.textDocument_selectionRange;

  @override
  LspJsonHandler<SelectionRangeParams> get jsonHandler =>
      SelectionRangeParams.jsonHandler;

  @override
  Future<ErrorOr<List<SelectionRange>?>> handle(SelectionRangeParams params,
      MessageInfo message, CancellationToken token) async {
    if (!isDartDocument(params.textDocument)) {
      return success(null);
    }

    final path = pathOfDoc(params.textDocument);
    return path.mapResult((path) async {
      final unit = await requireUnresolvedUnit(path);
      final positions = params.positions;
      final offsets = await unit.mapResult((unit) =>
          ErrorOr.all(positions.map((pos) => toOffset(unit.lineInfo, pos))));
      final allRanges = await offsets.mapResult(
          (offsets) => success(_getSelectionRangesForOffsets(offsets, unit)));

      return allRanges;
    });
  }

  SelectionRange _getSelectionRangesForOffset(
      CompilationUnit unit, int offset) {
    final lineInfo = unit.lineInfo;
    final computer = DartSelectionRangeComputer(unit, offset);
    final ranges = computer.compute();
    // Loop through the items starting at the end (the outermost range), using
    // each item as the parent for the next item.
    SelectionRange? last;
    for (var i = ranges.length - 1; i >= 0; i--) {
      final range = ranges[i];
      last = SelectionRange(
        range: toRange(lineInfo, range.offset, range.length),
        parent: last,
      );
    }

    // When there is no range for a given position, return an empty range at the
    // requested position. From the LSP spec:
    //
    // "To allow for results where some positions have selection ranges and
    //  others do not, result[i].range is allowed to be the empty range at
    //  positions[i]."
    return last ?? SelectionRange(range: toRange(lineInfo, offset, 0));
  }

  List<SelectionRange> _getSelectionRangesForOffsets(
      List<int> offsets, ErrorOr<ParsedUnitResult> unit) {
    return offsets
        .map((offset) => _getSelectionRangesForOffset(unit.result.unit, offset))
        .toList();
  }
}
