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

import 'package:compiler/src/common/names.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/indexed.dart';
import 'package:compiler/src/elements/names.dart';
import 'package:compiler/src/inferrer/abstract_value_domain.dart';
import 'package:compiler/src/js_model/js_world.dart';
import 'package:compiler/src/universe/call_structure.dart';
import 'package:compiler/src/universe/function_set.dart';
import 'package:compiler/src/universe/selector.dart';

class _QueuedMember {
  /// The member to be processed.
  final MemberEntity member;

  /// The class we want to look for ancestors of [member] from. This might be
  /// a supertype of member's enclosing class or a mixin application.
  final ClassEntity cls;

  /// Whether or not [cls] is the declarer of [member]. In most cases this is
  /// true when [cls] equals member's [MemberEntity.enclosingClass]. However
  /// for mixins this can be true when [cls] is the mixin application class.
  final bool isDeclaration;

  _QueuedMember(this.member, this.cls, {required this.isDeclaration});
}

class DynamicCallTarget {
  final MemberEntity member;
  final bool isVirtual;

  factory DynamicCallTarget.virtual(MemberEntity member) =>
      DynamicCallTarget(member, isVirtual: true);
  factory DynamicCallTarget.concrete(MemberEntity member) =>
      DynamicCallTarget(member, isVirtual: false);
  DynamicCallTarget(this.member, {required this.isVirtual});

  @override
  int get hashCode => Object.hash(member, isVirtual);

  @override
  bool operator ==(Object other) {
    return identical(this, other) ||
        (other is DynamicCallTarget &&
            member == other.member &&
            isVirtual == other.isVirtual);
  }

  @override
  String toString() => 'TargetResult($member, virtual: $isVirtual)';
}

class MemberHierarchyBuilder {
  final JClosedWorld closedWorld;
  final Map<SelectorMask, Iterable<DynamicCallTarget>> _callCache = {};
  final Map<Selector, Set<MemberEntity>> _selectorRoots = {};
  final Map<MemberEntity, Set<MemberEntity>> _overrides = {};

  MemberHierarchyBuilder(this.closedWorld);

  /// Uses [visited] to detect and avoid cycles in the override graph.
  void _forEachOverride(MemberEntity member,
      void Function(MemberEntity override) f, Set<MemberEntity> visited) {
    final overrides = _overrides[member];
    if (overrides == null) return;
    for (final override in overrides) {
      if (!visited.add(override)) continue;
      f(override);
      _forEachOverride(override, f, visited);
    }
  }

  /// Recursively applies [f] to each override of [entity].
  void forEachOverride(
      MemberEntity entity, void Function(MemberEntity override) f) {
    _forEachOverride(entity, f, {});
  }

  /// Finds the first non-strict superclass of [cls] that contains a member
  /// matching [selector] and returns that member.
  ///
  /// Returns the first non-abstract match found while ascending the class
  /// hierarchy. If no non-abstract matches are found then the first abstract
  /// match is used.
  ///
  /// If [virtualResult] is true, the resulting [DynamicCallTarget] will be
  /// virtual when the match is non-abstract and has overrides.
  /// Otherwise the resulting [DynamicCallTarget] is concrete.
  DynamicCallTarget? findSuperclassTarget(ClassEntity cls, Selector selector,
      {required bool virtualResult}) {
    MemberEntity? firstAbstractMatch;
    ClassEntity? current = cls;
    final elementEnv = closedWorld.elementEnvironment;
    while (current != null) {
      final match =
          elementEnv.lookupLocalClassMember(current, selector.memberName);
      if (match != null && !skipMember(match, selector)) {
        if (match.isAbstract) {
          firstAbstractMatch ??= match;
        } else {
          return DynamicCallTarget(match,
              isVirtual: virtualResult && _hasOverride(match));
        }
      }
      current = elementEnv.getSuperClass(current);
    }
    return firstAbstractMatch != null
        ? DynamicCallTarget.virtual(firstAbstractMatch)
        : null;
  }

  /// For each subclass/subtype try to find a member matching selector.
  ///
  /// If we find a match then it covers the entire subtree below that match so
  /// we do not need to check subclasses/subtypes below it.
  Iterable<DynamicCallTarget> findMatchingAncestors(
      ClassEntity baseCls, Selector selector,
      {required bool isSubtype}) {
    final Set<DynamicCallTarget> results = {};
    final Queue<ClassEntity> toVisit = Queue();
    final Set<ClassEntity> visited = {};
    void addSubclasses(ClassEntity cls) {
      for (final subclass in closedWorld.classHierarchy
          .getClassHierarchyNode(cls)
          .directSubclasses) {
        final subclassCls = subclass.cls;
        if (visited.add(subclassCls)) toVisit.add(subclassCls);
      }
    }

    void addSubtypes(ClassEntity cls) {
      for (final subtype
          in closedWorld.classHierarchy.getClassSet(baseCls).subtypeNodes) {
        final subtypeCls = subtype.cls;
        if (visited.add(subtypeCls)) toVisit.add(subtypeCls);
      }
    }

    addSubclasses(baseCls);
    if (isSubtype) {
      addSubtypes(baseCls);
      // We only need to add this in the subtype case because
      // `findMatchInSuperclass` will already check superclasses of `baseCls`.
      // If this is a subtype query then we need to make sure we add supertypes
      // of `baseCls`.
      toVisit.add(baseCls);
    }
    while (toVisit.isNotEmpty) {
      final current = toVisit.removeFirst();
      final match =
          findSuperclassTarget(current, selector, virtualResult: true);
      if (match != null) {
        results.add(match);
      } else {
        addSubclasses(current);
        if (isSubtype) {
          addSubtypes(current);
        }
      }
    }
    return results;
  }

  /// Returns the set of root member declarations for [selector]. [cls] acts as
  /// a subclass filter for these roots.
  ///
  /// The set of roots is the smallest set of members that are an ancestor of
  /// every implementation of [selector]. This is with the caveat that we
  /// consider each mixin application to declare a "copy" of each member of that
  /// mixin. They share the same [MemberEntity] but each copy is considered a
  /// separate potential root.
  Iterable<DynamicCallTarget> rootsForSelector(
      ClassEntity cls, Selector selector) {
    final roots = _selectorRoots[_normalizeSelector(selector)];
    if (roots == null) return const [];
    final classHierarchy = closedWorld.classHierarchy;
    return roots
        .where((r) =>
            selector.appliesStructural(r) &&
            classHierarchy.isSubclassOf(r.enclosingClass!, cls))
        .map((r) => DynamicCallTarget(r, isVirtual: _hasOverride(r)))
        .toSet();
  }

  /// Returns a set of common ancestors (not necessarily the smallest) for all
  /// possible targets when calling [selector] on an object with type
  /// [receiverType].
  ///
  /// Caches results for each receiver/selector pair. If [receiverType] is
  /// `null` the receiver is considered dynamic and any member that matches
  /// [selector] is a possible target. Also adds relevant [noSuchMethod] and
  /// `null` targets if needed for the call.
  Iterable<DynamicCallTarget> rootsForCall(
      AbstractValue? receiverType, Selector selector) {
    final domain = closedWorld.abstractValueDomain;
    receiverType ??= domain.dynamicType;
    final selectorMask = SelectorMask(selector, receiverType);
    final cachedResult = _callCache[selectorMask];
    if (cachedResult != null) return cachedResult;

    Iterable<DynamicCallTarget> targetsForReceiver =
        domain.findRootsOfTargets(receiverType, selector, this);

    // TODO(natebiggs): Can we calculate this as part of the above call to
    // findRootsOfTargets?
    final needsNoSuchMethod = selector != Selectors.noSuchMethod_ &&
        domain
            .needsNoSuchMethodHandling(receiverType, selector)
            .isPotentiallyTrue;

    final isNull = domain.isNull(receiverType);

    if (isNull.isPotentiallyTrue) {
      // Add relevant member if null is a potential target.
      final nullMatch = closedWorld.elementEnvironment.lookupLocalClassMember(
          closedWorld.commonElements.jsNullClass, selector.memberName);
      if (nullMatch != null) {
        targetsForReceiver = {
          ...targetsForReceiver,
          DynamicCallTarget.concrete(nullMatch)
        };
      }
    }

    final result = needsNoSuchMethod
        ? targetsForReceiver
            .followedBy(rootsForCall(receiverType, Selectors.noSuchMethod_))
            .toSet()
        : targetsForReceiver;

    return _callCache[selectorMask] = result;
  }

  /// Map call selectors to a getter with the same name. This allows us to
  /// ignore their call structure since overridden methods can have different
  /// call structures. This also handles method tear-offs.
  static Selector _normalizeSelector(Selector selector) =>
      selector.isCall ? Selector.getter(selector.memberName) : selector;

  static bool _skipMemberInternal(MemberEntity member) {
    return member.isStatic;
  }

  static bool skipMember(MemberEntity member, Selector selector) {
    return _skipMemberInternal(member) || !selector.appliesStructural(member);
  }

  bool _hasOverride(MemberEntity member) {
    return _overrides.containsKey(member);
  }

  static List<Selector> _selectorsForMember(MemberEntity member) {
    final List<Selector> result = [];
    if (member is FieldEntity) {
      // A field implicitly defines both a getter and setter. Each of these can
      // have different overrides so we consider them separately.
      result.add(Selector.getter(member.memberName));
      result.add(Selector.setter(member.memberName));
    } else {
      final selector = Selector.fromElement(member);
      result.add(_normalizeSelector(selector));
    }
    return result;
  }

  void _processNext(
      Queue<_QueuedMember> queue,
      Selector selector,
      Map<ClassEntity, MemberEntity?> roots,
      void Function(MemberEntity parent, MemberEntity override) join) {
    final state = queue.removeFirst();
    final cls = state.cls;
    final member = state.member;
    if (state.isDeclaration && !roots.containsKey(cls)) {
      // Only add the potential root if we're processing a declaration of
      // the member and have not already found an override for the class'
      // declaration.
      roots[cls] = member;
    }
    final elementEnv = closedWorld.elementEnvironment;
    final elementMap = closedWorld.elementMap;
    final name = selector.memberName;

    void addParent(
        MemberEntity parent, ClassEntity parentCls, bool fromSuperclass) {
      if ((_overrides[parent] ??= {}).add(member)) {
        join(parent, member);
      }

      // Both the class we are considering and the enclosing class of [member]
      // are not roots since we found an override for them.
      roots[cls] = null;
      roots[member.enclosingClass!] = null;

      // Enqueue parent to continue processing from there. parentCls can be a
      // mixin application since we consider these to have duplicates of the
      // mixin's members.
      queue.add(_QueuedMember(parent, parentCls, isDeclaration: true));
    }

    void processInterfaces(IndexedClass toProcess) {
      final interfaces = elementMap.getInterfaces(toProcess);
      for (final interface in interfaces) {
        final interfaceCls = interface.element;
        // For unnamed mixin applications, members can be owned by the
        // underlying mixin which is also an interface for that same
        // application. This would cause a self-override unless we explicitly
        // ignore that interface relationship.
        if (interfaceCls == member.enclosingClass) continue;
        final match = elementEnv.lookupLocalClassMember(interfaceCls, name);
        if (match != null &&
            !MemberHierarchyBuilder._skipMemberInternal(match)) {
          addParent(match, interfaceCls, false);
        } else {
          // The interface does not contain a match so enqueue the current
          // member to continue checking the superclasses and supertypes of the
          // interface.
          queue.add(_QueuedMember(member, interfaceCls, isDeclaration: false));
        }
      }
    }

    void addInterfaces(IndexedClass toProcess) {
      processInterfaces(toProcess);

      // Supertypes of the mixin for this class are also supertypes of this
      // class.
      final mixinClass = elementEnv.getEffectiveMixinClass(toProcess);
      if (mixinClass != null) {
        processInterfaces(mixinClass as IndexedClass);
      }
    }

    // Check and add any interfaces for the current class.
    addInterfaces(cls as IndexedClass);

    // Check each superclass in ascending order until we find an ancestor.
    ClassEntity? current = elementEnv.getSuperClass(cls);
    while (current != null) {
      final match = elementEnv.lookupLocalClassMember(current, name);
      if (match != null && !MemberHierarchyBuilder._skipMemberInternal(match)) {
        addParent(match, current, true);
        break;
      }

      // If this superclass does not declare a relevant member then check its
      // interfaces too since a supertype can contain an ancestor.
      addInterfaces(current as IndexedClass);
      current = elementEnv.getSuperClass(current);
    }
  }

  void _processMember(
      MemberEntity member,
      Map<Selector, Map<ClassEntity, MemberEntity?>> roots,
      void Function(MemberEntity parent, MemberEntity override) join,
      Queue<_QueuedMember> queue) {
    if (_skipMemberInternal(member)) return;
    final cls = member.enclosingClass!;
    final mixinUses = closedWorld.mixinUsesOf(cls);
    // Process each selector matching member separately.
    for (final selector in _selectorsForMember(member)) {
      for (final mixinUse in mixinUses) {
        queue.add(_QueuedMember(member, mixinUse, isDeclaration: true));
      }
      queue.add(_QueuedMember(member, cls, isDeclaration: true));
      final selectorRoots = roots[selector] ??= {};
      while (queue.isNotEmpty) {
        _processNext(queue, selector, selectorRoots, join);
      }
    }
  }

  void init(void Function(MemberEntity parent, MemberEntity override) join) {
    final liveMembers = closedWorld.liveInstanceMembers
        .followedBy(closedWorld.liveAbstractInstanceMembers);

    // Track root declarations for each selector encountered. Each inner map
    // tracks declarations of the selector. A null member indicates we found
    // an override for that declaration.
    final Map<Selector, Map<ClassEntity, MemberEntity?>> roots = {};
    final queue = Queue<_QueuedMember>();
    for (final member in liveMembers) {
      assert(queue.isEmpty);
      _processMember(member, roots, join, queue);
    }

    // Finalize roots for each selector. Deduplicate remaining root declarations
    // and store them for later.
    roots.forEach((selector, selectorRoots) {
      final validRoots = selectorRoots.values.whereType<MemberEntity>().toSet();
      if (validRoots.isNotEmpty) _selectorRoots[selector] = validRoots;
    });
  }

  // TODO(natebiggs): Clean up debug code below.
  void debugCall(String selectorName, String className,
      {bool nullReceiver = false,
      bool nullValue = false,
      bool subClass = false,
      bool subType = false,
      bool setter = false,
      CallStructure? call}) {
    final allMembers = closedWorld.liveInstanceMembers
        .followedBy(closedWorld.liveAbstractInstanceMembers);
    final cls = allMembers
        .firstWhere((e) => e.enclosingClass!.name == className)
        .enclosingClass!;
    final domain = closedWorld.abstractValueDomain;
    final receiver = nullValue
        ? domain.nullType
        : (nullReceiver
            ? null
            : (subClass
                ? domain.createNonNullSubclass(cls)
                : (subType
                    ? domain.createNonNullSubtype(cls)
                    : domain.createNullableExact(cls))));
    final name = Name(selectorName, null);
    final selector = call != null
        ? Selector.call(name, call)
        : (setter ? Selector.setter(name) : Selector.getter(name));

    print('Receiver: $receiver, Selector: $selector');
    print('Locate members: ${closedWorld.locateMembers(selector, receiver)}');
    print('Targets for call: ${rootsForCall(receiver, selector).toList()}');
  }

  void dumpOverrides([String? memberName]) {
    print(_overrides.entries
        .where((e) => memberName == null || e.key.name == memberName)
        .map((e) => '${e.key}\n  ${e.value.join('\n  ')}')
        .join('\n'));
  }

  void dumpRoots([String? selectorName]) {
    (_selectorRoots.entries
            .where((e) => selectorName == null || e.key.name == selectorName)
            .map((e) {
      final members = e.value.map((m) => m).toList();
      members.sort((a, b) => a.toString().compareTo(b.toString()));
      return MapEntry(e.key, members.join(', '));
    }).toList()
          ..sort((a, b) {
            final keyComp = a.key.toString().compareTo(b.key.toString());
            return keyComp != 0 ? keyComp : a.value.compareTo(b.value);
          }))
        .forEach((e) => print('${e.key}: ${e.value}'));
  }

  void dumpCache({String? selectorName, String? receiverString}) {
    _callCache.entries
        .where((e) =>
            (selectorName == null || e.key.name == selectorName) &&
            (receiverString == null ||
                e.key.receiver.toString().contains(receiverString)))
        .forEach((e) => print('${e.key}: ${e.value.join(', ')}'));
  }
}
