// 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.

library analyzer.task.model;

import 'dart:collection';
import 'dart:developer';

import 'package:analyzer/error/error.dart' show AnalysisError;
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer/src/task/driver.dart';
import 'package:analyzer/src/task/model.dart';
import 'package:front_end/src/base/analysis_target.dart';

export 'package:front_end/src/base/analysis_target.dart' show AnalysisTarget;

/**
 * A function that converts the given [key] and [value] into a [TaskInput].
 */
typedef TaskInput<E> BinaryFunction<K, V, E>(K key, V value);

/**
 * A function that takes an analysis [context] and an analysis [target] and
 * returns an analysis task. Such functions are passed to a [TaskDescriptor] to
 * be used to create the described task.
 */
typedef AnalysisTask BuildTask(AnalysisContext context, AnalysisTarget target);

/**
 * A function that takes the target for which a task will produce results and
 * returns a map from input names to descriptions of the analysis results needed
 * by the task in order for the task to be performed. Such functions are passed
 * to a [TaskDescriptor] to be used to determine the inputs needed by the task.
 */
typedef Map<String, TaskInput> CreateTaskInputs(AnalysisTarget target);

/**
 * A function that takes the target for which a task will produce results and
 * returns an indication of how suitable the task is for the target. Such
 * functions are passed to a [TaskDescriptor] to be used to determine their
 * suitability for computing results.
 */
typedef TaskSuitability SuitabilityFor(AnalysisTarget target);

/**
 * A function that converts an object of the type [B] into a [TaskInput].
 * This is used, for example, by a [ListTaskInput] to create task inputs
 * for each value in a list of values.
 */
typedef TaskInput<E> UnaryFunction<B, E>(B object);

/**
 * An [AnalysisTarget] wrapper for an [AnalysisContext].
 */
class AnalysisContextTarget implements AnalysisTarget {
  static final AnalysisContextTarget request = new AnalysisContextTarget(null);

  final AnalysisContext context;

  AnalysisContextTarget(this.context);

  @override
  Source get librarySource => null;

  @override
  Source get source => null;
}

/**
 * An object used to compute one or more analysis results associated with a
 * single target.
 *
 * Clients must extend this class when creating new tasks.
 */
abstract class AnalysisTask {
  /**
   * A queue storing the last 10 task descriptions for diagnostic purposes.
   */
  static final LimitedQueue<String> LAST_TASKS = new LimitedQueue<String>(10);

  /**
   * A table mapping the types of analysis tasks to the number of times each
   * kind of task has been performed.
   */
  static final Map<Type, int> countMap = new HashMap<Type, int>();

  /**
   * A table mapping the types of analysis tasks to user tags used to collect
   * timing data for the Observatory.
   */
  static Map<Type, UserTag> tagMap = new HashMap<Type, UserTag>();

  /**
   * A table mapping the types of analysis tasks to stopwatches used to compute
   * how much time was spent executing each kind of task.
   */
  static final Map<Type, Stopwatch> stopwatchMap =
      new HashMap<Type, Stopwatch>();

  /**
   * The context in which the task is to be performed.
   */
  final AnalysisContext context;

  /**
   * The target for which result values are being produced.
   */
  final AnalysisTarget target;

  /**
   * A table mapping input names to input values.
   */
  Map<String, dynamic> inputs;

  /**
   * A table mapping result descriptors whose values are produced by this task
   * to the values that were produced.
   */
  Map<ResultDescriptor, dynamic> outputs =
      new HashMap<ResultDescriptor, dynamic>();

  /**
   * The exception that was thrown while performing this task, or `null` if the
   * task completed successfully.
   */
  CaughtException caughtException;

  /**
   * If a dependency cycle was found while computing the inputs for the task,
   * the set of [WorkItem]s contained in the cycle (if there are overlapping
   * cycles, this is the set of all [WorkItem]s in the entire strongly
   * connected component).  Otherwise, `null`.
   */
  List<WorkItem> dependencyCycle;

  /**
   * Initialize a newly created task to perform analysis within the given
   * [context] in order to produce results for the given [target].
   */
  AnalysisTask(this.context, this.target);

  /**
   * Return a textual description of this task.
   */
  String get description;

  /**
   * Return the descriptor that describes this task.
   */
  TaskDescriptor get descriptor;

  /**
   * Indicates whether the task is capable of handling dependency cycles.  A
   * task that overrides this getter to return `true` must be prepared for the
   * possibility that it will be invoked with a non-`null` value of
   * [dependencyCycle], and with not all of its inputs computed.
   */
  bool get handlesDependencyCycles => false;

  /**
   * Return the value of the input with the given [name], or `null` if the input
   * value is not defined.
   */
  Object getOptionalInput(String name) {
    if (inputs == null || !inputs.containsKey(name)) {
      return null;
    }
    return inputs[name];
  }

  /**
   * Return the value of the input with the given [name]. Throw an exception if
   * the input value is not defined.
   */
  Object/*=E*/ getRequiredInput/*<E>*/(String name) {
    if (inputs == null || !inputs.containsKey(name)) {
      throw new AnalysisException("Could not $description: missing $name");
    }
    return inputs[name] as Object/*=E*/;
  }

  /**
   * Return the source associated with the target. Throw an exception if
   * the target is not associated with a source.
   */
  Source getRequiredSource() {
    Source source = target.source;
    if (source == null) {
      throw new AnalysisException("Could not $description: missing source");
    }
    return source;
  }

  /**
   * Perform this analysis task, protected by an exception handler.
   *
   * This method should throw an [AnalysisException] if an exception occurs
   * while performing the task. If other kinds of exceptions are thrown they
   * will be wrapped in an [AnalysisException].
   *
   * If no exception is thrown, this method must fully populate the [outputs]
   * map (have a key/value pair for each result that this task is expected to
   * produce).
   */
  void internalPerform();

  /**
   * Perform this analysis task. When this method returns, either the [outputs]
   * map should be fully populated (have a key/value pair for each result that
   * this task is expected to produce) or the [caughtException] should be set.
   *
   * Clients may not override this method.
   */
  void perform() {
    try {
      _safelyPerform();
    } on AnalysisException catch (exception, stackTrace) {
      caughtException = new CaughtException(exception, stackTrace);
      AnalysisEngine.instance.logger
          .logError("Task failed: $description", caughtException);
    }
  }

  @override
  String toString() => description;

  /**
   * Given a strongly connected component, find and return a list of
   * [TargetedResult]s that describes a cyclic path within the cycle.  Returns
   * null if no cyclic path is found.
   */
  List<TargetedResult> _findCyclicPath(List<WorkItem> cycle) {
    WorkItem findInCycle(AnalysisTarget target, ResultDescriptor descriptor) {
      for (WorkItem item in cycle) {
        if (target == item.target && descriptor == item.spawningResult) {
          return item;
        }
      }
      return null;
    }

    HashSet<WorkItem> active = new HashSet<WorkItem>();
    List<TargetedResult> path = null;
    bool traverse(WorkItem item) {
      if (!active.add(item)) {
        // We've found a cycle
        path = <TargetedResult>[];
        return true;
      }
      for (TargetedResult result in item.inputTargetedResults) {
        WorkItem item = findInCycle(result.target, result.result);
        // Ignore edges that leave the cycle.
        if (item != null) {
          if (traverse(item)) {
            // This edge is in a cycle (or leads to a cycle) so add it to the
            // path
            path.add(result);
            return true;
          }
        }
      }
      // There was no cycle.
      return false;
    }

    if (cycle.length > 0) {
      traverse(cycle[0]);
    }
    return path;
  }

  /**
   * Perform this analysis task, ensuring that all exceptions are wrapped in an
   * [AnalysisException].
   *
   * Clients may not override this method.
   */
  void _safelyPerform() {
    try {
      //
      // Store task description for diagnostics.
      //
      LAST_TASKS.add(description);

      //
      // Report that this task is being performed.
      //
      String contextName = context.name;
      if (contextName == null) {
        contextName = 'unnamed';
      }
      AnalysisEngine.instance.instrumentationService
          .logAnalysisTask(contextName, this);
      //
      // Gather statistics on the performance of the task.
      //
      int count = countMap[runtimeType];
      countMap[runtimeType] = count == null ? 1 : count + 1;
//      UserTag tag = tagMap.putIfAbsent(
//          runtimeType, () => new UserTag(runtimeType.toString()));
      Stopwatch stopwatch = stopwatchMap[runtimeType];
      if (stopwatch == null) {
        stopwatch = new Stopwatch();
        stopwatchMap[runtimeType] = stopwatch;
      }
//      UserTag previousTag = tag.makeCurrent();
//      try {
      stopwatch.start();
      //
      // Actually perform the task.
      //
      try {
        if (dependencyCycle != null && !handlesDependencyCycles) {
          throw new InfiniteTaskLoopException(
              this, dependencyCycle, _findCyclicPath(dependencyCycle));
        }
        internalPerform();
      } finally {
        stopwatch.stop();
      }
//      } finally {
//        previousTag.makeCurrent();
//      }
    } on AnalysisException {
      rethrow;
    } on ModificationTimeMismatchError {
      rethrow;
    } catch (exception, stackTrace) {
      throw new AnalysisException(
          'Unexpected exception while performing $description',
          new CaughtException(exception, stackTrace));
    }
  }
}

/**
 * A description of a [List]-based analysis result that can be computed by an
 * [AnalysisTask].
 *
 * Clients may not extend, implement or mix-in this class.
 */
abstract class ListResultDescriptor<E> implements ResultDescriptor<List<E>> {
  /**
   * Initialize a newly created analysis result to have the given [name] and
   * [defaultValue]. If a [cachingPolicy] is provided, it will control how long
   * values associated with this result will remain in the cache.
   */
  factory ListResultDescriptor(String name, List<E> defaultValue,
          {ResultCachingPolicy<List<E>> cachingPolicy}) =
      ListResultDescriptorImpl<E>;

  @override
  ListTaskInput<E> of(AnalysisTarget target, {bool flushOnAccess: false});
}

/**
 * A description of an input to an [AnalysisTask] that can be used to compute
 * that input.
 *
 * Clients may not extend, implement or mix-in this class.
 */
abstract class ListTaskInput<E> implements TaskInput<List<E>> {
  /**
   * Return a task input that can be used to compute a flatten list whose
   * elements are combined [subListResult]'s associated with those elements.
   */
  ListTaskInput/*<V>*/ toFlattenListOf/*<V>*/(
      ListResultDescriptor/*<V>*/ subListResult);

  /**
   * Return a task input that can be used to compute a list whose elements are
   * the result of passing the elements of this input to the [mapper] function.
   */
  ListTaskInput/*<V>*/ toList/*<V>*/(UnaryFunction<E, dynamic/*=V*/ > mapper);

  /**
   * Return a task input that can be used to compute a list whose elements are
   * [valueResult]'s associated with those elements.
   */
  ListTaskInput/*<V>*/ toListOf/*<V>*/(ResultDescriptor/*<V>*/ valueResult);

  /**
   * Return a task input that can be used to compute a map whose keys are the
   * elements of this input and whose values are the result of passing the
   * corresponding key to the [mapper] function.
   */
  MapTaskInput<E, dynamic/*=V*/ > toMap/*<V>*/(
      UnaryFunction<E, dynamic/*=V*/ > mapper);

  /**
   * Return a task input that can be used to compute a map whose keys are the
   * elements of this input and whose values are the [valueResult]'s associated
   * with those elements.
   */
  MapTaskInput<AnalysisTarget, dynamic/*=V*/ > toMapOf/*<V>*/(
      ResultDescriptor/*<V>*/ valueResult);
}

/**
 * A description of an input with a [Map] based values.
 *
 * Clients may not extend, implement or mix-in this class.
 */
abstract class MapTaskInput<K, V> implements TaskInput<Map<K, V>> {
  /**
   * [V] must be a [List].
   * Return a task input that can be used to compute a list whose elements are
   * the result of passing keys [K] and the corresponding elements of [V] to
   * the [mapper] function.
   */
  TaskInput<List/*<E>*/ > toFlattenList/*<E>*/(
      BinaryFunction<K, dynamic /*element of V*/, dynamic/*=E*/ > mapper);
}

/**
 * Instances of this class are thrown when a task detects that the modification
 * time of a cache entry is not the same as the actual modification time.  This
 * means that any analysis results based on the content of the target cannot be
 * used anymore and must be invalidated.
 */
class ModificationTimeMismatchError {
  final Source source;

  ModificationTimeMismatchError(this.source);
}

/**
 * A policy object that can compute sizes of results and provide the maximum
 * active and idle sizes that can be kept in the cache.
 *
 * All the [ResultDescriptor]s with the same [ResultCachingPolicy] instance
 * share the same total size in a cache.
 *
 * Clients may implement this class when implementing plugins.
 */
abstract class ResultCachingPolicy<T> {
  /**
   * Return the maximum total size of results that can be kept in the cache
   * while analysis is in progress.
   */
  int get maxActiveSize;

  /**
   * Return the maximum total size of results that can be kept in the cache
   * while analysis is idle.
   */
  int get maxIdleSize;

  /**
   * Return the size of the given [object].
   */
  int measure(T object);
}

/**
 * A description of an analysis result that can be computed by an [AnalysisTask].
 *
 * Clients may not extend, implement or mix-in this class.
 */
abstract class ResultDescriptor<V> {
  /**
   * A comparator that can be used to sort result descriptors by their name.
   */
  static final Comparator<ResultDescriptor> SORT_BY_NAME =
      (ResultDescriptor first, ResultDescriptor second) =>
          first.name.compareTo(second.name);

  /**
   * Initialize a newly created analysis result to have the given [name] and
   * [defaultValue].
   *
   * The given [cachingPolicy] is used to limit the total size of results
   * described by this descriptor. If no policy is specified, the results are
   * never evicted from the cache, and removed only when they are invalidated.
   */
  factory ResultDescriptor(String name, V defaultValue,
      {ResultCachingPolicy<V> cachingPolicy}) = ResultDescriptorImpl<V>;

  /**
   * Return the caching policy for results described by this descriptor.
   */
  ResultCachingPolicy<V> get cachingPolicy;

  /**
   * Return the default value for results described by this descriptor.
   */
  V get defaultValue;

  /**
   * Return the name of this descriptor.
   */
  String get name;

  /**
   * Return a task input that can be used to compute this result for the given
   * [target]. If [flushOnAccess] is `true` then the value of this result that
   * is associated with the [target] will be flushed when it is accessed.
   */
  TaskInput<V> of(AnalysisTarget target, {bool flushOnAccess: false});
}

/**
 * A specification of the given [result] for the given [target].
 *
 * Clients may not extend, implement or mix-in this class.
 */
class TargetedResult {
  /**
   * An empty list of results.
   */
  static final List<TargetedResult> EMPTY_LIST = const <TargetedResult>[];

  /**
   * The target with which the result is associated.
   */
  final AnalysisTarget target;

  /**
   * The result associated with the target.
   */
  final ResultDescriptor result;

  /**
   * Initialize a new targeted result.
   */
  TargetedResult(this.target, this.result);

  @override
  int get hashCode {
    return JenkinsSmiHash.combine(target.hashCode, result.hashCode);
  }

  @override
  bool operator ==(other) {
    return other is TargetedResult &&
        other.target == target &&
        other.result == result;
  }

  @override
  String toString() => '$result for $target';
}

/**
 * A description of an [AnalysisTask].
 *
 * Clients may not extend, implement or mix-in this class.
 */
abstract class TaskDescriptor {
  /**
   * Initialize a newly created task descriptor to have the given [name] and to
   * describe a task that takes the inputs built using the given [inputBuilder],
   * and produces the given [results]. The [buildTask] function will be used to
   * create the instance of [AnalysisTask] being described. If provided, the
   * [isAppropriateFor] function will be used to determine whether the task can
   * be used on a specific target.
   */
  factory TaskDescriptor(String name, BuildTask buildTask,
      CreateTaskInputs inputBuilder, List<ResultDescriptor> results,
      {SuitabilityFor suitabilityFor}) = TaskDescriptorImpl;

  /**
   * Return the builder used to build the inputs to the task.
   */
  CreateTaskInputs get createTaskInputs;

  /**
   * Return the name of the task being described.
   */
  String get name;

  /**
   * Return a list of the analysis results that will be computed by this task.
   */
  List<ResultDescriptor> get results;

  /**
   * Create and return a task that is described by this descriptor that can be
   * used to compute results based on the given [inputs].
   */
  AnalysisTask createTask(AnalysisContext context, AnalysisTarget target,
      Map<String, dynamic> inputs);

  /**
   * Return an indication of how suitable this task is for the given [target].
   */
  TaskSuitability suitabilityFor(AnalysisTarget target);
}

/**
 * A description of an input to an [AnalysisTask] that can be used to compute
 * that input.
 *
 * Clients may not extend, implement or mix-in this class.
 */
abstract class TaskInput<V> {
  /**
   * Create and return a builder that can be used to build this task input.
   */
  TaskInputBuilder<V> createBuilder();

  /**
   * Return a task input that can be used to compute a list whose elements are
   * the result of passing the result of this input to the [mapper] function.
   */
  ListTaskInput/*<E>*/ mappedToList/*<E>*/(List/*<E>*/ mapper(V value));
}

/**
 * An object used to build the value associated with a single [TaskInput].
 *
 * All builders work by requesting one or more results (each result being
 * associated with a target). The interaction pattern is modeled after the class
 * [Iterator], in which the method [moveNext] is invoked to move from one result
 * request to the next. The getters [currentResult] and [currentTarget] are used
 * to get the result and target of the current request. The value of the result
 * must be supplied using the [currentValue] setter before [moveNext] can be
 * invoked to move to the next request. When [moveNext] returns `false`,
 * indicating that there are no more requests, the method [inputValue] can be
 * used to access the value of the input that was built.
 *
 * Clients may not extend, implement or mix-in this class.
 */
abstract class TaskInputBuilder<V> {
  /**
   * Return the result that needs to be computed, or `null` if [moveNext] has
   * not been invoked or if the last invocation of [moveNext] returned `false`.
   */
  ResultDescriptor get currentResult;

  /**
   * Return the target for which the result needs to be computed, or `null` if
   * [moveNext] has not been invoked or if the last invocation of [moveNext]
   * returned `false`.
   */
  AnalysisTarget get currentTarget;

  /**
   * Set the [value] that was computed for the current result.
   *
   * Throws a [StateError] if [moveNext] has not been invoked or if the last
   * invocation of [moveNext] returned `false`.
   */
  void set currentValue(Object value);

  /**
   * Return `true` if the value accessed by this input builder should be flushed
   * from the cache at the time it is retrieved.
   */
  bool get flushOnAccess;

  /**
   * Return the [value] that was computed by this builder.
   *
   * Throws a [StateError] if [moveNext] has not been invoked or if the last
   * invocation of [moveNext] returned `true`.
   *
   * Returns `null` if no value could be computed due to a circular dependency.
   */
  V get inputValue;

  /**
   * Record that no value is available for the current result, due to a
   * circular dependency.
   *
   * Throws a [StateError] if [moveNext] has not been invoked or if the last
   * invocation of [moveNext] returned `false`.
   */
  void currentValueNotAvailable();

  /**
   * Move to the next result that needs to be computed in order to build the
   * inputs for a task. Return `true` if there is another result that needs to
   * be computed, or `false` if the inputs have been computed.
   *
   * It is safe to invoke [moveNext] after it has returned `false`. In this case
   * [moveNext] has no effect and will again return `false`.
   *
   * Throws a [StateError] if the value of the current result has not been
   * provided using [currentValue].
   */
  bool moveNext();
}

/**
 * An indication of how suitable a task is for a given target.
 */
enum TaskSuitability { NONE, LOWEST, HIGHEST }

/**
 * [WorkManager]s are used to drive analysis.
 *
 * They know specific of the targets and results they care about,
 * so they can request analysis results in optimal order.
 *
 * Clients may implement this class when implementing plugins.
 */
abstract class WorkManager {
  /**
   * Notifies the manager about changes in the explicit source list.
   */
  void applyChange(List<Source> addedSources, List<Source> changedSources,
      List<Source> removedSources);

  /**
   * Notifies the managers that the given set of priority [targets] was set.
   */
  void applyPriorityTargets(List<AnalysisTarget> targets);

  /**
   * Return a list of all of the errors associated with the given [source].
   * The list of errors will be empty if the source is not known to the context
   * or if there are no errors in the source. The errors contained in the list
   * can be incomplete.
   */
  List<AnalysisError> getErrors(Source source);

  /**
   * Return the next [TargetedResult] that this work manager wants to be
   * computed, or `null` if this manager doesn't need any new results.
   *
   * Note, that it is not guaranteed that this result will be computed, it is
   * up to the work manager to check whether the result is already computed
   * (for example during the next [getNextResult] invocation) or computation
   * of the same result should be requested again.
   */
  TargetedResult getNextResult();

  /**
   * Return the priority if the next work order this work manager want to be
   * computed. The [AnalysisDriver] will perform the work order with
   * the highest priority.
   *
   * Even if the returned value is [WorkOrderPriority.NONE], it still does not
   * guarantee that [getNextResult] will return not `null`.
   */
  WorkOrderPriority getNextResultPriority();

  /**
   * Notifies the manager about analysis options changes.
   */
  void onAnalysisOptionsChanged();

  /**
   * Notifies the manager about [SourceFactory] changes.
   */
  void onSourceFactoryChanged();

  /**
   * Notifies the manager that the given [outputs] were produced for
   * the given [target].
   */
  void resultsComputed(
      AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs);
}

/**
 * The priorities of work orders returned by [WorkManager]s.
 *
 * New priorities may be added with time, clients need to tolerate this.
 */
enum WorkOrderPriority {
  /**
   * Responding to an user's action.
   */
  INTERACTIVE,

  /**
   * Computing information for priority sources.
   */
  PRIORITY,

  /**
   * A work should be done, but without any special urgency.
   */
  NORMAL,

  /**
   * Nothing to do.
   */
  NONE
}
