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

library universe.function_set;

import '../common/names.dart' show Identifiers, Selectors;
import '../elements/entities.dart';
import '../inferrer/abstract_value_domain.dart';
import '../util/util.dart' show Hashing, Setlet;
import 'selector.dart' show Selector;

// TODO(kasperl): This actually holds getters and setters just fine
// too and stricly they aren't functions. Maybe this needs a better
// name -- something like ElementSet seems a bit too generic.
class FunctionSet {
  final Map<String, FunctionSetNode> _nodes;

  factory FunctionSet(Iterable<MemberEntity> liveInstanceMembers) {
    Map<String, FunctionSetNode> nodes = {};
    for (MemberEntity member in liveInstanceMembers) {
      String name = member.name!;
      (nodes[name] ??= FunctionSetNode(name)).add(member);
    }
    return FunctionSet.internal(nodes);
  }

  FunctionSet.internal(this._nodes);

  bool contains(MemberEntity element) {
    assert(element.isInstanceMember);
    assert(!element.isAbstract);
    String name = element.name!;
    FunctionSetNode? node = _nodes[name];
    return (node != null) ? node.contains(element) : false;
  }

  /// Returns all the functions that may be invoked with the [selector] on a
  /// receiver with the given [constraint]. The returned elements may include
  /// noSuchMethod handlers that are potential targets indirectly through the
  /// noSuchMethod mechanism.
  Iterable<MemberEntity> filter(
      Selector selector, AbstractValue? receiver, AbstractValueDomain domain) {
    return query(selector, receiver, domain).functions;
  }

  /// Returns the mask for the potential receivers of a dynamic call to
  /// [selector] on [constraint].
  ///
  /// This will narrow the constraints of [constraint] to a [TypeMask] of the
  /// set of classes that actually implement the selected member or implement
  /// the handling 'noSuchMethod' where the selected member is unimplemented.
  AbstractValue receiverType(
      Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
    return query(selector, receiver, domain).computeMask(domain);
  }

  SelectorMask _createSelectorMask(
      Selector selector, AbstractValue? receiver, AbstractValueDomain domain) {
    return receiver != null
        ? SelectorMask(selector, receiver)
        : SelectorMask(selector, domain.dynamicType);
  }

  /// Returns the set of functions that can be the target of a call to
  /// [selector] on a receiver constrained by [constraint] including
  /// 'noSuchMethod' methods where applicable.
  FunctionSetQuery query(
      Selector selector, AbstractValue? receiver, AbstractValueDomain domain) {
    String name = selector.name;
    SelectorMask selectorMask = _createSelectorMask(selector, receiver, domain);
    SelectorMask noSuchMethodMask =
        SelectorMask(Selectors.noSuchMethod_, selectorMask.receiver);
    FunctionSetNode? node = _nodes[name];
    FunctionSetNode? noSuchMethods = _nodes[Identifiers.noSuchMethod_];
    if (node != null) {
      return node.query(selectorMask, domain, noSuchMethods, noSuchMethodMask);
    }
    // If there is no method that matches [selector] we know we can
    // only hit [:noSuchMethod:].
    if (noSuchMethods == null) {
      return const EmptyFunctionSetQuery();
    }
    return noSuchMethods.query(noSuchMethodMask, domain);
  }

  void forEach(void action(MemberEntity member)) {
    _nodes.forEach((String name, FunctionSetNode node) {
      node.forEach(action);
    });
  }
}

/// A selector/constraint pair representing the dynamic invocation of [selector]
/// on a receiver constrained by [constraint].
class SelectorMask {
  final Selector selector;
  final AbstractValue receiver;
  @override
  final int hashCode;

  SelectorMask(this.selector, this.receiver)
      : this.hashCode =
            Hashing.mixHashCodeBits(selector.hashCode, receiver.hashCode);

  String get name => selector.name;

  bool applies(MemberEntity element, AbstractValueDomain domain) {
    if (!selector.appliesUnnamed(element)) return false;
    return domain
        .isTargetingMember(receiver, element, selector.memberName)
        .isPotentiallyTrue;
  }

  bool needsNoSuchMethodHandling(AbstractValueDomain domain) {
    return domain
        .needsNoSuchMethodHandling(receiver, selector)
        .isPotentiallyTrue;
  }

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    return other is SelectorMask &&
        selector == other.selector &&
        receiver == other.receiver;
  }

  @override
  String toString() => '($selector,$receiver)';
}

/// A node in the [FunctionSet] caching all [FunctionSetQuery] object for
/// selectors with the same [name].
class FunctionSetNode {
  final String name;
  final Map<SelectorMask, FunctionSetQuery> cache = {};

  // Initially, we keep the elements in a list because it is more
  // compact than a hash set. Once we get enough elements, we change
  // the representation to be a set to get faster contains checks.
  static const int MAX_ELEMENTS_IN_LIST = 8;
  Iterable<MemberEntity> elements = [];
  bool isList = true;

  FunctionSetNode(this.name);

  void add(MemberEntity element) {
    assert(element.name == name);
    // We try to avoid clearing the cache unless we have to. For that
    // reason we keep the explicit contains check even though the add
    // method ends up doing the work again (for sets).
    if (!elements.contains(element)) {
      if (isList && elements.length >= MAX_ELEMENTS_IN_LIST) {
        elements = elements.toSet();
        isList = false;
      }
      if (isList) {
        final list = elements as List<MemberEntity>;
        list.add(element);
      } else {
        final set = elements as Set<MemberEntity>;
        set.add(element);
      }
      if (!cache.isEmpty) cache.clear();
    }
  }

  void remove(MemberEntity element) {
    assert(element.name == name);
    if (isList) {
      final list = elements as List<MemberEntity>;
      int index = list.indexOf(element);
      if (index < 0) return;
      MemberEntity last = list.removeLast();
      if (index != list.length) {
        list[index] = last;
      }
      if (!cache.isEmpty) cache.clear();
    } else {
      final set = elements as List<MemberEntity>;
      if (set.remove(element)) {
        // To avoid wobbling between the two representations, we do
        // not transition back to the list representation even if we
        // end up with few enough elements at this point.
        if (!cache.isEmpty) cache.clear();
      }
    }
  }

  bool contains(MemberEntity element) {
    assert(element.name == name);
    return elements.contains(element);
  }

  void forEach(void action(MemberEntity member)) {
    elements.forEach(action);
  }

  /// Returns the set of functions that can be the target of [selectorMask]
  /// including no such method handling where applicable.
  FunctionSetQuery query(SelectorMask selectorMask, AbstractValueDomain domain,
      [FunctionSetNode? noSuchMethods, SelectorMask? noSuchMethodMask]) {
    assert(selectorMask.name == name);
    FunctionSetQuery? result = cache[selectorMask];
    if (result != null) return result;

    Setlet<MemberEntity>? functions;
    for (MemberEntity element in elements) {
      if (selectorMask.applies(element, domain)) {
        // Defer the allocation of the functions set until we are
        // sure we need it. This allows us to return immutable empty
        // lists when the filtering produced no results.
        functions ??= Setlet();
        functions.add(element);
      }
    }

    // If we cannot ensure a method will be found at runtime, we also
    // add [noSuchMethod] implementations that apply to [mask] as
    // potential targets.
    if (noSuchMethods != null &&
        selectorMask.needsNoSuchMethodHandling(domain)) {
      // If [noSuchMethods] was provided then [noSuchMethodMask] should also
      // have been provided.
      FunctionSetQuery noSuchMethodQuery =
          noSuchMethods.query(noSuchMethodMask!, domain);
      if (!noSuchMethodQuery.functions.isEmpty) {
        functions ??= Setlet();
        functions.addAll(noSuchMethodQuery.functions);
      }
    }
    cache[selectorMask] = result = (functions != null)
        ? FullFunctionSetQuery(functions)
        : const EmptyFunctionSetQuery();
    return result;
  }

  @override
  String toString() {
    StringBuffer sb = StringBuffer();
    sb.write('FunctionSetNode(');
    String comma = '';
    cache.forEach((mask, query) {
      sb.write(comma);
      sb.write('$mask=$query');
      comma = ',';
    });
    sb.write(')');
    return sb.toString();
  }
}

/// A set of functions that are the potential targets of all call sites sharing
/// the same receiver mask and selector.
abstract class FunctionSetQuery {
  const FunctionSetQuery();

  /// Compute the type of all potential receivers of this function set.
  AbstractValue computeMask(AbstractValueDomain domain);

  /// Returns all potential targets of this function set.
  Iterable<MemberEntity> get functions;
}

class EmptyFunctionSetQuery implements FunctionSetQuery {
  const EmptyFunctionSetQuery();

  @override
  AbstractValue computeMask(AbstractValueDomain domain) => domain.emptyType;

  @override
  Iterable<MemberEntity> get functions => const [];

  @override
  String toString() => '<empty>';
}

class FullFunctionSetQuery implements FunctionSetQuery {
  @override
  final Iterable<MemberEntity> functions;

  AbstractValue? _receiver;

  FullFunctionSetQuery(this.functions);

  @override
  AbstractValue computeMask(AbstractValueDomain domain) {
    return _receiver ??= domain.computeReceiver(functions);
  }

  @override
  String toString() => '$_receiver:$functions';
}
