// Copyright (c) 2017, 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:analyzer/dart/analysis/results.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart' show SourceRange;
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/utilities/navigation/navigation.dart';
import 'package:analyzer_plugin/utilities/pair.dart';

/// A concrete implementation of [DartNavigationRequest].
class DartNavigationRequestImpl implements DartNavigationRequest {
  @override
  final ResourceProvider resourceProvider;

  @override
  final int length;

  @override
  final int offset;

  @override
  final ResolvedUnitResult result;

  /// Initialize a newly create request with the given data.
  DartNavigationRequestImpl(
      this.resourceProvider, this.offset, this.length, this.result);

  @override
  String get path => result.path;
}

/// A concrete implementation of [NavigationCollector].
class NavigationCollectorImpl implements NavigationCollector {
  /// Whether the collector is collecting target code locations. Computers can
  /// skip computing these if this is false.
  @override
  final bool collectCodeLocations;

  /// A list of navigation regions.
  final List<NavigationRegion> regions = <NavigationRegion>[];

  final Map<SourceRange, List<int>> regionMap = <SourceRange, List<int>>{};

  /// All the unique targets referenced by [regions].
  final List<NavigationTarget> targets = <NavigationTarget>[];

  final Map<Pair<ElementKind, Location>, int> targetMap =
      <Pair<ElementKind, Location>, int>{};

  /// All the unique files referenced by [targets].
  final List<String> files = <String>[];

  final Map<String, int> fileMap = <String, int>{};

  NavigationCollectorImpl({this.collectCodeLocations = false});

  @override
  void addRange(
      SourceRange range, ElementKind targetKind, Location targetLocation,
      {Location? targetCodeLocation}) {
    addRegion(range.offset, range.length, targetKind, targetLocation,
        targetCodeLocation: targetCodeLocation);
  }

  @override
  void addRegion(
      int offset, int length, ElementKind targetKind, Location targetLocation,
      {Location? targetCodeLocation}) {
    var range = SourceRange(offset, length);
    // add new target
    var targets = regionMap.putIfAbsent(range, () => <int>[]);
    var targetIndex =
        _addTarget(targetKind, targetLocation, targetCodeLocation);
    targets.add(targetIndex);
  }

  void createRegions() {
    regionMap.forEach((range, targets) {
      var region = NavigationRegion(range.offset, range.length, targets);
      regions.add(region);
    });
    regions.sort((NavigationRegion first, NavigationRegion second) {
      return first.offset - second.offset;
    });
  }

  int _addFile(String file) {
    var index = fileMap[file];
    if (index == null) {
      index = files.length;
      files.add(file);
      fileMap[file] = index;
    }
    return index;
  }

  int _addTarget(ElementKind kind, Location location, Location? codeLocation) {
    var pair = Pair<ElementKind, Location>(kind, location);
    var index = targetMap[pair];
    if (index == null) {
      var file = location.file;
      var fileIndex = _addFile(file);
      index = targets.length;
      var target = NavigationTarget(kind, fileIndex, location.offset,
          location.length, location.startLine, location.startColumn,
          codeOffset: collectCodeLocations ? codeLocation?.offset : null,
          codeLength: collectCodeLocations ? codeLocation?.length : null);
      targets.add(target);
      targetMap[pair] = index;
    }
    return index;
  }
}
