// Copyright (c) 2015, 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 '../chunk.dart';
import '../constants.dart';
import '../fast_hash.dart';

/// A constraint that determines the different ways a related set of chunks may
/// be split.
class Rule extends FastHash {
  /// The rule used for dummy chunks.
  static final Rule dummy = Rule.hard();

  /// Rule value that splits no chunks.
  ///
  /// Every rule is required to treat this value as fully unsplit.
  static const unsplit = 0;

  /// Rule constraint value that means "any value as long as something splits".
  ///
  /// It disallows [unsplit] but allows any other value.
  static const mustSplit = -1;

  /// The number of different states this rule can be in.
  ///
  /// Each state determines which set of chunks using this rule are split and
  /// which aren't. Values range from zero to one minus this. Value zero
  /// always means "no chunks are split" and increasing values by convention
  /// mean increasingly undesirable splits.
  ///
  /// By default, a rule has two values: fully unsplit and fully split.
  int get numValues => 2;

  /// The rule value that forces this rule into its maximally split state.
  ///
  /// By convention, this is the highest of the range of allowed values.
  int get fullySplitValue => numValues - 1;

  int get cost => _cost;
  final int _cost;

  /// During line splitting [LineSplitter] sets this to the index of this
  /// rule in its list of rules.
  int? index;

  /// If `true`, the rule has been "hardened" meaning it's been placed into a
  /// permanent "must fully split" state.
  bool get isHardened => _isHardened;
  bool _isHardened = false;

  /// The other [Rule]s that are implied this one.
  ///
  /// In many cases, if a split occurs inside an expression, surrounding rules
  /// also want to split too. For example, a split in the middle of an argument
  /// forces the entire argument list to also split.
  ///
  /// This tracks those relationships. If this rule splits, (sets its value to
  /// [fullySplitValue]) then all of the surrounding implied rules are also set
  /// to their fully split value.
  ///
  /// This contains all direct as well as transitive relationships. If A
  /// contains B which contains C, C's outerRules contains both B and A.
  final Set<Rule> _implied = <Rule>{};

  /// Marks [other] as implied by this one.
  ///
  /// That means that if this rule splits, then [other] is force to split too.
  void imply(Rule other) {
    _implied.add(other);
  }

  /// Whether this rule cares about rules that it contains.
  ///
  /// If `true` then inner rules will constrain this one and force it to split
  /// when they split. Otherwise, it can split independently of any contained
  /// rules.
  bool get splitsOnInnerRules => true;

  Rule([int? cost]) : _cost = cost ?? Cost.normal;

  /// Creates a new rule that is already fully split.
  Rule.hard() : _cost = 0 {
    // Set the cost to zero since it will always be applied, so there's no
    // point in penalizing it.
    //
    // Also, this avoids doubled counting in literal blocks where there is both
    // a split in the outer chunk containing the block and the inner hard split
    // between the elements or statements.
    harden();
  }

  /// Fixes this rule into a "fully split" state.
  void harden() {
    _isHardened = true;
  }

  /// Returns `true` if [chunk] should split when this rule has [value].
  bool isSplit(int value, Chunk chunk) {
    if (_isHardened) return true;

    if (value == Rule.unsplit) return false;

    // Let the subclass decide.
    return isSplitAtValue(value, chunk);
  }

  /// Subclasses can override this to determine which values split which chunks.
  ///
  /// By default, this assumes every chunk splits.
  bool isSplitAtValue(int value, Chunk chunk) => true;

  /// Given that this rule has [value], determine if [other]'s value should be
  /// constrained.
  ///
  /// Allows relationships between rules like "if I split, then this should
  /// split too". Returns a non-negative value to force [other] to take that
  /// value. Returns -1 to allow [other] to take any non-zero value. Returns
  /// `null` to not constrain other.
  int? constrain(int value, Rule other) {
    // By default, any containing rule will be fully split if this one is split.
    if (value == Rule.unsplit) return null;
    if (_implied.contains(other)) return other.fullySplitValue;

    return null;
  }

  /// A protected method for subclasses to add the rules that they constrain
  /// to [rules].
  ///
  /// Called by [Rule] the first time [constrainedRules] is accessed.
  void addConstrainedRules(Set<Rule> rules) {}

  /// Discards constraints on any rule that doesn't have an index.
  ///
  /// This is called by [LineSplitter] after it has indexed all of the in-use
  /// rules. A rule may end up with a constraint on a rule that's no longer
  /// used by any chunk. This can happen if the rule gets hardened, or if it
  /// simply never got used by a chunk. For example, a rule for splitting an
  /// empty list of metadata annotations.
  ///
  /// This removes all of those.
  void forgetUnusedRules() {
    _implied.retainWhere((rule) => rule.index != null);

    // Clear the cached ones too.
    _constrainedRules = null;
    _allConstrainedRules = null;
  }

  /// The other [Rule]s that this rule places immediate constraints on.
  Set<Rule> get constrainedRules {
    // Lazy initialize this on first use. Note: Assumes this is only called
    // after the chunks have been written and any constraints have been wired
    // up.
    var rules = _constrainedRules;
    if (rules != null) return rules;

    rules = _implied.toSet();
    addConstrainedRules(rules);
    _constrainedRules = rules;
    return rules;
  }

  Set<Rule>? _constrainedRules;

  /// The transitive closure of all of the rules this rule places constraints
  /// on, directly or indirectly, including itself.
  Set<Rule> get allConstrainedRules {
    var rules = _allConstrainedRules;
    if (rules != null) return rules;

    rules = {};
    _traverseConstraints(rules, this);
    _allConstrainedRules = rules;
    return rules;
  }

  /// Traverses the constraint graph of [rule] adding everything to [rules].
  void _traverseConstraints(Set<Rule> rules, Rule rule) {
    if (rules.contains(rule)) return;

    rules.add(rule);
    for (var rule in rule.constrainedRules) {
      _traverseConstraints(rules, rule);
    }
  }

  Set<Rule>? _allConstrainedRules;

  @override
  String toString() => '$id';
}
