// Copyright (c) 2020, 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.

/// Code for managing comment reference lookups in dartdoc.
library;

import 'dart:core';

import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/scope.dart';
import 'package:collection/collection.dart';
import 'package:dartdoc/src/model/library.dart';
import 'package:dartdoc/src/model/model_element.dart';
import 'package:dartdoc/src/model/nameable.dart';
import 'package:dartdoc/src/model/prefix.dart';
import 'package:meta/meta.dart';

class _ReferenceChildrenLookup {
  final String lookup;
  final List<String> remaining;

  _ReferenceChildrenLookup(this.lookup, this.remaining);

  @override
  String toString() =>
      '$lookup ($lookup${remaining.isNotEmpty ? ".${remaining.join(".")}" : ''})';
}

/// Support comment reference lookups on a Nameable object.
mixin CommentReferable implements Nameable {
  /// For any [CommentReferable] where an analyzer [Scope] exists (or can
  /// be constructed), implement this.  This will take priority over
  /// lookups via [referenceChildren].  Can be cached.
  Scope? get scope => null;

  String? get href => null;

  /// Looks up a comment reference by its component parts.
  ///
  /// If [tryParents] is true, try looking up the same reference in any parents
  /// of `this`. Will skip over results that do not pass a given [filter] and
  /// keep searching.
  @nonVirtual
  CommentReferable? referenceBy(
    List<String> reference, {
    required bool Function(CommentReferable?) filter,
    bool tryParents = true,
    Iterable<CommentReferable>? parentOverrides,
  }) {
    parentOverrides ??= referenceParents;
    if (reference.isEmpty) {
      return tryParents ? null : this;
    }
    for (var referenceLookup in _childLookups(reference)) {
      // First attempt: Ask analyzer's `Scope.lookup` API.
      var result = _lookupViaScope(referenceLookup, filter: filter);
      if (result != null) {
        if (result is Prefix &&
            result.name == '_' &&
            library!.element2.featureSet.isEnabled(Feature.wildcard_variables)) {
          // A wildcard import prefix is non-binding.
          continue;
        }
        return result;
      }

      // Second attempt: Look through `referenceChildren`.
      final referenceChildren = this.referenceChildren;
      final childrenResult = referenceChildren[referenceLookup.lookup];
      if (childrenResult != null) {
        var result = _recurseChildrenAndFilter(
          referenceLookup,
          childrenResult,
          filter: filter,
        );
        if (result != null) {
          return result;
        }
      }
    }
    // If we can't find it in children, try searching parents if allowed.
    if (tryParents) {
      for (var parent in parentOverrides) {
        var result = parent.referenceBy(
          reference,
          tryParents: true,
          parentOverrides: referenceGrandparentOverrides,
          filter: filter,
        );
        if (result != null) return result;
      }
    }
    return null;
  }

  /// Looks up references by [scope], skipping over results that do not match
  /// [filter].
  ///
  /// Override if [Scope.lookup] may return elements not corresponding to a
  /// [CommentReferable], but you still want to have an implementation of
  /// [scope].
  CommentReferable? _lookupViaScope(
    _ReferenceChildrenLookup referenceLookup, {
    required bool Function(CommentReferable?) filter,
  }) {
    Element2? resultElement;
    final scope = this.scope;
    if (scope != null) {
      resultElement = scope.lookupPreferGetter(referenceLookup.lookup);
      if (resultElement == null) return null;
    }

    if (resultElement == null) {
      if (this case ModelElement(:var modelNode?)) {
        var references = modelNode.commentData?.references;
        if (references != null) {
          resultElement = references[referenceLookup.lookup]?.element;
        }
      }
    }

    if (resultElement == null) {
      return null;
    }

    ModelElement result;
    if (resultElement is PropertyAccessorElement2) {
      final variable = resultElement.variable3!;
      if (variable.isSynthetic) {
        // First, cache the synthetic variable, so that the
        // PropertyAccessorElement getter and/or setter are set (see
        // `Field.new` regarding `enclosingCombo`).
        packageGraph.getModelForElement(variable);
        // Then, use the result for the PropertyAccessorElement.
        result = packageGraph.getModelForElement(resultElement);
      } else {
        result = packageGraph.getModelForElement(variable);
      }
    } else {
      result = packageGraph.getModelForElement(resultElement);
    }
    return _recurseChildrenAndFilter(referenceLookup, result, filter: filter);
  }

  /// Given a [result] found in an implementation of [_lookupViaScope] or
  /// [_ReferenceChildrenLookup], recurse through children, skipping over
  /// results that do not match the filter.
  CommentReferable? _recurseChildrenAndFilter(
    _ReferenceChildrenLookup referenceLookup,
    CommentReferable result, {
    required bool Function(CommentReferable?) filter,
  }) {
    CommentReferable? returnValue = result;
    if (referenceLookup.remaining.isNotEmpty) {
      returnValue = result.referenceBy(referenceLookup.remaining,
          tryParents: false, filter: filter);
    } else if (!filter(result)) {
      returnValue = result.referenceBy([referenceLookup.lookup],
          tryParents: false, filter: filter);
    }
    if (!filter(returnValue)) {
      returnValue = null;
    }
    return returnValue;
  }

  /// A list of lookups that should be attempted on children based on
  /// [reference].
  ///
  /// This allows us to deal with libraries that may have separators in them.
  /// [referenceBy] stops at the first one found.
  Iterable<_ReferenceChildrenLookup> _childLookups(List<String> reference) =>
      reference
          .mapIndexed((index, _) => _ReferenceChildrenLookup(
              reference.sublist(0, index + 1).join('.'),
              reference.sublist(index + 1)))
          .toList(growable: false);

  /// Map of [referenceName] to the elements that are a member of `this`, but
  /// not this model element itself.  Can be cached.
  ///
  /// There is no need to duplicate references here that can be found via
  /// [scope].
  Map<String, CommentReferable> get referenceChildren;

  /// Iterable of immediate "parents" to try resolving component parts.
  /// [referenceBy] stops at the first parent where a part is found.
  /// Can be cached.
  // TODO(jcollins-g): Rationalize the different "enclosing" types so that
  // this doesn't duplicate `[enclosingElement]` in many cases.
  // TODO(jcollins-g): Implement comment reference resolution via categories,
  // making the iterable make sense here.
  Iterable<CommentReferable> get referenceParents;

  /// Replace the parents of parents.  [referenceBy] ignores whatever might
  /// otherwise be implied by the [referenceParents] of [referenceParents],
  /// replacing them with this.
  Iterable<CommentReferable>? get referenceGrandparentOverrides => null;

  // TODO(jcollins-g): Enforce that reference name is always the same
  // as [ModelElement.name].  Easier/possible after old lookup code is gone.
  String get referenceName => name;

  // TODO(jcollins-g): Eliminate need for this in markdown_processor.
  Library? get library => null;

  /// For testing / comparison only, get the comment referable from where this
  /// `ElementType` was defined.  Override where an [Element2] is available.
  @internal
  CommentReferable get definingCommentReferable => this;
}

extension on Scope {
  /// Prefer the getter for a bundled lookup if both exist.
  Element2? lookupPreferGetter(String id) {
    var result = lookup(id);
    return result.getter2 ?? result.setter2;
  }
}

/// A set of utility methods for helping build
/// [CommentReferable.referenceChildren] out of collections of other
/// [CommentReferable]s.
extension CommentReferableEntryGenerators<T extends CommentReferable>
    on Iterable<T> {
  /// Creates reference entries for this Iterable.
  ///
  /// If there is a conflict with [referable], the included [MapEntry] uses
  /// [referable]'s [CommentReferable.referenceName] as a prefix.
  Map<String, T> explicitOnCollisionWith(CommentReferable referable) => {
        for (var r in this)
          if (r.referenceName == referable.referenceName)
            '${referable.referenceName}.${r.referenceName}': r
          else
            r.referenceName: r,
      };

  /// A mapping from each [CommentReferable]'s name to itself.
  Map<String, T> get asMapByName => {
        for (var r in this) r.referenceName: r,
      };

  /// Returns all values not of this type.
  List<T> whereNotType<U>() => [
        for (var referable in this)
          if (referable is! U) referable,
      ];
}
