// 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/element/type_provider.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/constant/evaluation.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/summary/link.dart' as graph
    show DependencyWalker, Node;

/// Compute values of the given [constants] with correct ordering.
void computeConstants(
    TypeProvider typeProvider,
    TypeSystemImpl typeSystem,
    DeclaredVariables declaredVariables,
    List<ConstantEvaluationTarget> constants,
    ExperimentStatus experimentStatus) {
  var walker = _ConstantWalker(declaredVariables, experimentStatus);

  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 ExperimentStatus experimentStatus;
  final Map<ConstantEvaluationTarget, _ConstantNode> nodeMap = {};

  _ConstantWalker(this.declaredVariables, this.experimentStatus);

  @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, experimentStatus.triple_shift);
  }

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