// Copyright (c) 2018, 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 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/src/dart/constant/evaluation.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/summary/link.dart' as graph
    show DependencyWalker, Node;

/// Compute values of the given [constants] with correct ordering.
void computeConstants(DeclaredVariables declaredVariables,
    List<ConstantEvaluationTarget> constants, FeatureSet featureSet) {
  var walker = _ConstantWalker(declaredVariables, featureSet);

  for (var constant in constants) {
    var node = walker._getNode(constant);
    if (!node.isEvaluated) {
      walker.walk(node);
    }
  }
}

/// [graph.Node] that is used to compute constants in dependency order.
class _ConstantNode extends graph.Node<_ConstantNode> {
  final _ConstantWalker walker;
  final ConstantEvaluationTarget constant;

  _ConstantNode(this.walker, this.constant);

  @override
  bool get isEvaluated => constant.isConstantEvaluated;

  @override
  List<_ConstantNode> computeDependencies() {
    return walker._computeDependencies(this);
  }
}

/// [graph.DependencyWalker] for computing constants and detecting cycles.
class _ConstantWalker extends graph.DependencyWalker<_ConstantNode> {
  final DeclaredVariables declaredVariables;
  final FeatureSet featureSet;
  final Map<ConstantEvaluationTarget, _ConstantNode> nodeMap = {};

  _ConstantWalker(this.declaredVariables, this.featureSet);

  @override
  void evaluate(_ConstantNode node) {
    _getEvaluationEngine(node).computeConstantValue(node.constant);
  }

  @override
  void evaluateScc(List<_ConstantNode> scc) {
    var constantsInCycle = scc.map((node) => node.constant);
    for (var node in scc) {
      var constant = node.constant;
      if (constant is ConstructorElementImpl) {
        constant.isCycleFree = false;
      }
      _getEvaluationEngine(node).generateCycleError(constantsInCycle, constant);
    }
  }

  List<_ConstantNode> _computeDependencies(_ConstantNode node) {
    var evaluationEngine = _getEvaluationEngine(node);
    var targets = <ConstantEvaluationTarget>[];
    evaluationEngine.computeDependencies(node.constant, targets.add);
    return targets.map(_getNode).toList();
  }

  ConstantEvaluationEngine _getEvaluationEngine(_ConstantNode node) {
    return ConstantEvaluationEngine(
      declaredVariables: declaredVariables,
      isNonNullableByDefault: featureSet.isEnabled(Feature.non_nullable),
    );
  }

  _ConstantNode _getNode(ConstantEvaluationTarget constant) {
    return nodeMap.putIfAbsent(
      constant,
      () => _ConstantNode(this, constant),
    );
  }
}
