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

/// Repository of constraints corresponding to the code being migrated.
///
/// This data structure carries information from the second pass of migration
/// ([ConstraintGatherer]) to the third (which creates individual code
/// modifications from each constraint).
abstract class Constraints {
  /// Records a new constraint equation.
  void record(
      Iterable<ConstraintVariable> conditions, ConstraintVariable consequence);
}

/// Representation of a single boolean variable in the constraint solver.
class ConstraintVariable {
  /// A special boolean variable whose value is known to be `true`.
  static final ConstraintVariable always = _Always();

  /// A list of all constraints containing this variable on their left hand side
  /// that may not have been satisfied yet.
  final _dependencies = <_Clause>[];

  /// The value assigned to this constraint variable by the solution currently
  /// being computed.
  bool _value = false;

  /// If this variable represents a disjunction ("or") of several other
  /// variables, the variables in the disjunction.  Otherwise a singleton list
  /// containing `this`.
  final List<ConstraintVariable> _disjunctionParts;

  ConstraintVariable() : _disjunctionParts = List.filled(1, null) {
    _disjunctionParts[0] = this;
  }

  /// Creates a [ConstraintVariable] representing a disjunction ("or") of
  /// several other variables.
  ///
  /// Additional constraints will be recorded in [constraints] to ensure that
  /// the solution will be consistent.
  factory ConstraintVariable.or(
      Constraints constraints, ConstraintVariable a, ConstraintVariable b) {
    if (a == null) return b;
    if (b == null) return a;
    var parts = a.disjunctionParts.toList();
    parts.addAll(b.disjunctionParts);
    assert(parts.length > 1);
    var result = ConstraintVariable._(parts);
    constraints.record([a], result);
    constraints.record([b], result);
    return result;
  }

  ConstraintVariable._(this._disjunctionParts);

  /// If this variable represents a disjunction ("or") of several other
  /// variables, the variables in the disjunction.  Otherwise a singleton list
  /// containing `this`.
  Iterable<ConstraintVariable> get disjunctionParts => _disjunctionParts;

  /// Indicates whether this variable represents a disjunction ("or") of several
  /// other variables.
  bool get isDisjunction => _disjunctionParts.length > 1;

  /// The value assigned to this constraint variable by the solution currently
  /// being computed.
  bool get value => _value;

  @override
  String toString() =>
      isDisjunction ? '(${_disjunctionParts.join(' | ')})' : super.toString();
}

/// The core of the migration tool's constraint solver.  This class implements
/// unit propagation (see https://en.wikipedia.org/wiki/Unit_propagation),
/// extended to support disjunctions.
///
/// The extension works approximately as follows: first we perform ordinary unit
/// propagation, accumulating a list of any disjunction variables that need to
/// be assigned a value of `true`.  Once this finishes, we heuristically choose
/// one of these disjunction variables and ensure that it is assigned a value of
/// `true` by setting one of its constituent variables to `true` and propagating
/// again.  Once all disjunctions have been resolved, we have a final solution.
class Solver extends Constraints {
  /// Clauses that should be evaluated as part of ordinary unit propagation.
  final _pending = <_Clause>[];

  /// Disjunction variables that have been determined by unit propagation to be
  /// `true`, but for which we have not yet propagated the `true` value to one
  /// of the constituent variables.
  final _pendingDisjunctions = <ConstraintVariable>[];

  /// Heuristically resolves any pending disjunctions.
  void applyHeuristics() {
    while (_pendingDisjunctions.isNotEmpty) {
      var disjunction = _pendingDisjunctions.removeLast();
      if (disjunction.disjunctionParts.any((v) => v.value)) continue;
      // TODO(paulberry): smarter heuristics
      var choice = disjunction.disjunctionParts.first;
      record([], choice);
    }
  }

  @override
  void record(Iterable<ConstraintVariable> conditions,
      covariant ConstraintVariable consequence) {
    var _conditions = List<ConstraintVariable>.from(conditions);
    var clause = _Clause(_conditions, consequence);
    int i = 0;
    while (i < _conditions.length) {
      ConstraintVariable variable = _conditions[i];
      if (variable._value) {
        int j = _conditions.length - 1;
        _conditions[i] = _conditions[j];
        _conditions.removeLast();
        continue;
      }
      variable._dependencies.add(clause);
      i++;
    }
    if (i == 0) {
      if (!consequence._value) {
        consequence._value = true;
        if (consequence.isDisjunction) {
          _pendingDisjunctions.add(consequence);
        }
        _pending.addAll(consequence._dependencies);
        _propagate();
      }
    } else {
      consequence._dependencies.add(clause);
    }
  }

  /// Performs ordinary unit propagation, recording any disjunctions encountered
  /// in [_pendingDisjunctions].
  void _propagate() {
    while (_pending.isNotEmpty) {
      var clause = _pending.removeLast();
      var conditions = clause.conditions;
      int i = 0;
      while (i < conditions.length) {
        ConstraintVariable variable = conditions[i];
        if (variable._value) {
          int j = conditions.length - 1;
          conditions[i] = conditions[j];
          conditions.removeLast();
          continue;
        }
        i++;
      }
      if (i == 0) {
        var consequence = clause.consequence;
        if (!consequence._value) {
          consequence._value = true;
          if (consequence.isDisjunction) {
            _pendingDisjunctions.add(consequence);
          }
          _pending.addAll(consequence._dependencies);
        }
      }
    }
  }
}

/// The special singleton [ConstraintVariable] whose value is always `true`.
class _Always extends ConstraintVariable {
  _Always() {
    _value = true;
  }

  @override
  String toString() => 'always';
}

/// A single equation in a system of constraints.
class _Clause {
  /// The conditions on the left hand side of the equation.
  final List<ConstraintVariable> conditions;

  /// The single variable on the right hand side of the equation.
  final ConstraintVariable consequence;

  _Clause(this.conditions, this.consequence);
}
