// 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 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/driver.dart';
import 'package:analyzer/src/task/inputs.dart';
import 'package:analyzer/src/task/manager.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../generated/test_support.dart';
import 'test_support.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(AnalysisDriverTest);
    defineReflectiveTests(CycleAwareDependencyWalkerTest);
    defineReflectiveTests(WorkItemTest);
    defineReflectiveTests(WorkOrderTest);
  });
}

class AbstractDriverTest {
  TaskManager taskManager = new TaskManager();
  List<WorkManager> workManagers = <WorkManager>[];
  _InternalAnalysisContextMock context = new _InternalAnalysisContextMock();
  AnalysisDriver analysisDriver;

  void setUp() {
    context = new _InternalAnalysisContextMock();
    analysisDriver = new AnalysisDriver(taskManager, workManagers, context);
  }
}

@reflectiveTest
class AnalysisDriverTest extends AbstractDriverTest {
  _WorkManagerMock workManager1 = new _WorkManagerMock();
  _WorkManagerMock workManager2 = new _WorkManagerMock();

  AnalysisTarget target1 = new TestSource('/1.dart');
  AnalysisTarget target2 = new TestSource('/2.dart');

  ResultDescriptor result1 = new ResultDescriptor('result1', -1);
  ResultDescriptor result2 = new ResultDescriptor('result2', -2);

  TaskDescriptor descriptor1;
  TaskDescriptor descriptor2;

  void setUp() {
    super.setUp();
    workManager1.nextResultPriority = WorkOrderPriority.NONE;
    workManager2.nextResultPriority = WorkOrderPriority.NONE;

    workManagers.add(workManager1);
    workManagers.add(workManager2);
  }

  test_computeResult() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor result = new ResultDescriptor('result', null);
    TestAnalysisTask task;
    TaskDescriptor descriptor = new TaskDescriptor(
        'task', (context, target) => task, (target) => {}, [result]);
    task = new TestAnalysisTask(context, target, descriptor: descriptor);
    taskManager.addTaskDescriptor(descriptor);

    analysisDriver.computeResult(target, result);
    expect(context.getCacheEntry(target).getValue(result), 1);
  }

  test_create() {
    expect(analysisDriver, isNotNull);
    expect(analysisDriver.context, context);
    expect(analysisDriver.currentWorkOrder, isNull);
    expect(analysisDriver.taskManager, taskManager);
  }

  test_createNextWorkOrder_highLow() {
    _configureDescriptors12();
    workManager1.nextResultPriority = WorkOrderPriority.PRIORITY;
    workManager2.nextResultPriority = WorkOrderPriority.NORMAL;
    workManager1.nextResult = new TargetedResult(target1, result1);
    WorkOrder workOrder = analysisDriver.createNextWorkOrder();
    expect(workOrder, isNotNull);
    expect(workOrder.moveNext(), true);
    expect(workOrder.current.target, target1);
    expect(workOrder.current.descriptor, descriptor1);
  }

  test_createNextWorkOrder_lowHigh() {
    _configureDescriptors12();
    workManager1.nextResultPriority = WorkOrderPriority.NORMAL;
    workManager2.nextResultPriority = WorkOrderPriority.PRIORITY;
    workManager2.nextResult = new TargetedResult(target1, result1);
    WorkOrder workOrder = analysisDriver.createNextWorkOrder();
    expect(workOrder, isNotNull);
    expect(workOrder.moveNext(), true);
    expect(workOrder.current.target, target1);
    expect(workOrder.current.descriptor, descriptor1);
  }

  test_createNextWorkOrder_none() {
    _configureDescriptors12();
    workManager1.nextResultPriority = WorkOrderPriority.NONE;
    workManager2.nextResultPriority = WorkOrderPriority.NONE;
    expect(analysisDriver.createNextWorkOrder(), isNull);
  }

  test_createWorkOrderForResult_aboutToComputeResult() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor result = new ResultDescriptor('result', null);
    TaskDescriptor descriptor = new TaskDescriptor(
        'task',
        (context, target) => new TestAnalysisTask(context, target),
        (target) => {},
        [result]);
    taskManager.addTaskDescriptor(descriptor);
    context.getCacheEntry(target).setState(result, CacheState.INVALID);
    // has result
    {
      context.aboutToComputeResultMap[result] = true;
      WorkOrder workOrder =
          analysisDriver.createWorkOrderForResult(target, result);
      expect(workOrder, isNull);
    }
    // no result
    {
      context.aboutToComputeResultMap[result] = false;
      WorkOrder workOrder =
          analysisDriver.createWorkOrderForResult(target, result);
      expect(workOrder, isNotNull);
    }
  }

  test_createWorkOrderForResult_error() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor result = new ResultDescriptor('result', null);
    CaughtException exception = new CaughtException(null, null);
    context
        .getCacheEntry(target)
        .setErrorState(exception, <ResultDescriptor>[result]);

    expect(analysisDriver.createWorkOrderForResult(target, result), isNull);
  }

  test_createWorkOrderForResult_inProcess() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor result = new ResultDescriptor('result', null);
    context.getCacheEntry(target).setState(result, CacheState.IN_PROCESS);

    expect(analysisDriver.createWorkOrderForResult(target, result), isNull);
  }

  test_createWorkOrderForResult_invalid() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor result = new ResultDescriptor('result', null);
    TaskDescriptor descriptor = new TaskDescriptor(
        'task',
        (context, target) => new TestAnalysisTask(context, target),
        (target) => {},
        [result]);
    taskManager.addTaskDescriptor(descriptor);
    context.getCacheEntry(target).setState(result, CacheState.INVALID);

    WorkOrder workOrder =
        analysisDriver.createWorkOrderForResult(target, result);
    expect(workOrder, isNotNull);
  }

  test_createWorkOrderForResult_valid() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor<String> result =
        new ResultDescriptor<String>('result', null);
    context
        .getCacheEntry(target)
        .setValue(result, '', const <TargetedResult>[]);

    expect(analysisDriver.createWorkOrderForResult(target, result), isNull);
  }

  test_createWorkOrderForTarget_complete_generalTarget_generalResult() {
    _createWorkOrderForTarget(true, false, false);
  }

  test_createWorkOrderForTarget_complete_generalTarget_priorityResult() {
    _createWorkOrderForTarget(true, false, true);
  }

  test_createWorkOrderForTarget_complete_priorityTarget_generalResult() {
    _createWorkOrderForTarget(true, true, false);
  }

  test_createWorkOrderForTarget_complete_priorityTarget_priorityResult() {
    _createWorkOrderForTarget(true, true, true);
  }

  test_createWorkOrderForTarget_incomplete_generalTarget_generalResult() {
    _createWorkOrderForTarget(false, false, false);
  }

  test_createWorkOrderForTarget_incomplete_generalTarget_priorityResult() {
    _createWorkOrderForTarget(false, false, true);
  }

  test_createWorkOrderForTarget_incomplete_priorityTarget_generalResult() {
    _createWorkOrderForTarget(false, true, false);
  }

  test_createWorkOrderForTarget_incomplete_priorityTarget_priorityResult() {
    _createWorkOrderForTarget(false, true, true);
  }

  test_performAnalysisTask() {
    _configureDescriptors12();
    workManager1.nextResult = new TargetedResult(target1, result1);

    workManager1.nextResultPriority = WorkOrderPriority.NORMAL;
    expect(analysisDriver.performAnalysisTask(), true);
    expect(analysisDriver.performAnalysisTask(), true);

    workManager1.nextResultPriority = WorkOrderPriority.NONE;
    expect(analysisDriver.performAnalysisTask(), false);
  }

  test_performAnalysisTask_infiniteLoop_handled() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor<int> resultA = new ResultDescriptor<int>('resultA', -1);
    ResultDescriptor<int> resultB = new ResultDescriptor<int>('resultB', -2);
    // configure tasks
    TestAnalysisTask task1;
    TestAnalysisTask task2;
    TaskDescriptor descriptor1 = new TaskDescriptor(
        'task1',
        (context, target) => task1,
        (target) => {'inputB': new SimpleTaskInput<int>(target, resultB)},
        [resultA]);
    TaskDescriptor descriptor2 = new TaskDescriptor(
        'task2',
        (context, target) => task2,
        (target) => {'inputA': new SimpleTaskInput<int>(target, resultA)},
        [resultB]);
    task1 = new TestAnalysisTask(context, target,
        descriptor: descriptor1,
        results: [resultA],
        value: 10,
        handlesDependencyCycles: true);
    task2 = new TestAnalysisTask(context, target,
        descriptor: descriptor2,
        results: [resultB],
        value: 20,
        handlesDependencyCycles: true);
    taskManager.addTaskDescriptor(descriptor1);
    taskManager.addTaskDescriptor(descriptor2);
    // configure WorkManager
    workManager1.nextResultPriority = WorkOrderPriority.NORMAL;
    workManager1.nextResult = new TargetedResult(target, resultB);
    // prepare work order
    while (analysisDriver.performAnalysisTask()) {
      workManager1.nextResultPriority = WorkOrderPriority.NONE;
    }
    Set<TaskDescriptor> expectedCycle = [descriptor1, descriptor2].toSet();
    expect(task1.dependencyCycle, isNotNull);
    expect(task1.dependencyCycle.map((workItem) => workItem.descriptor).toSet(),
        expectedCycle);
    expect(task2.dependencyCycle, isNotNull);
    expect(task2.dependencyCycle.map((workItem) => workItem.descriptor).toSet(),
        expectedCycle);
    CaughtException exception = context.getCacheEntry(target).exception;
    expect(exception, isNull);
    expect(context.getCacheEntry(target).getValue(resultA), 10);
    expect(context.getCacheEntry(target).getValue(resultB), 20);
  }

  test_performAnalysisTask_infiniteLoop_unhandled() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor<int> resultA = new ResultDescriptor<int>('resultA', -1);
    ResultDescriptor<int> resultB = new ResultDescriptor<int>('resultB', -2);
    // configure tasks
    TestAnalysisTask task1;
    TestAnalysisTask task2;
    TaskDescriptor descriptor1 = new TaskDescriptor(
        'task1',
        (context, target) => task1,
        (target) => {'inputB': new SimpleTaskInput<int>(target, resultB)},
        [resultA]);
    TaskDescriptor descriptor2 = new TaskDescriptor(
        'task2',
        (context, target) => task2,
        (target) => {'inputA': new SimpleTaskInput<int>(target, resultA)},
        [resultB]);
    task1 = new TestAnalysisTask(context, target, descriptor: descriptor1);
    task2 = new TestAnalysisTask(context, target, descriptor: descriptor2);
    taskManager.addTaskDescriptor(descriptor1);
    taskManager.addTaskDescriptor(descriptor2);
    // configure WorkManager
    workManager1.nextResultPriority = WorkOrderPriority.NORMAL;
    workManager1.nextResult = new TargetedResult(target, resultB);
    // prepare work order
    expect(analysisDriver.performAnalysisTask(), true);
    expect(analysisDriver.performAnalysisTask(), true);
    CaughtException exception = context.getCacheEntry(target).exception;
    expect(exception, isNotNull);
    expect(exception.exception, new TypeMatcher<InfiniteTaskLoopException>());
  }

  test_performAnalysisTask_inputsFirst() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor<int> resultA = new ResultDescriptor<int>('resultA', -1);
    ResultDescriptor<int> resultB = new ResultDescriptor<int>('resultB', -2);
    // configure tasks
    TestAnalysisTask task1;
    TestAnalysisTask task2;
    TaskDescriptor descriptor1 = new TaskDescriptor(
        'task1', (context, target) => task1, (target) => {}, [resultA]);
    TaskDescriptor descriptor2 = new TaskDescriptor(
        'task2',
        (context, target) => task2,
        (target) => {'inputA': new SimpleTaskInput<int>(target, resultA)},
        [resultB]);
    task1 = new TestAnalysisTask(context, target,
        descriptor: descriptor1, results: [resultA], value: 10);
    task2 = new TestAnalysisTask(context, target,
        descriptor: descriptor2, value: 20);
    taskManager.addTaskDescriptor(descriptor1);
    taskManager.addTaskDescriptor(descriptor2);
    // configure WorkManager
    workManager1.nextResultPriority = WorkOrderPriority.NORMAL;
    workManager1.nextResult = new TargetedResult(target, resultB);
    // prepare work order
    expect(analysisDriver.performAnalysisTask(), true);
    expect(context.getCacheEntry(target).getValue(resultA), -1);
    expect(context.getCacheEntry(target).getValue(resultB), -2);
    // compute resultA
    expect(analysisDriver.performAnalysisTask(), true);
    expect(context.getCacheEntry(target).getValue(resultA), 10);
    expect(context.getCacheEntry(target).getValue(resultB), -2);
    // compute resultB
    expect(analysisDriver.performAnalysisTask(), true);
    expect(context.getCacheEntry(target).getValue(resultA), 10);
    expect(context.getCacheEntry(target).getValue(resultB), 20);
    // done
    workManager1.nextResultPriority = WorkOrderPriority.NONE;
    expect(analysisDriver.performAnalysisTask(), false);
  }

  test_performAnalysisTask_onResultComputed() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor result = new ResultDescriptor('result', null);
    TestAnalysisTask task;
    TaskDescriptor descriptor = new TaskDescriptor(
        'task', (context, target) => task, (target) => {}, [result]);
    task = new TestAnalysisTask(context, target,
        descriptor: descriptor, value: 42);
    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);

    bool streamNotified = false;
    analysisDriver.onResultComputed(result).listen((event) {
      streamNotified = true;
      expect(event.context, same(context));
      expect(event.target, same(target));
      expect(event.descriptor, same(result));
      expect(event.value, 42);
    });
    analysisDriver.performWorkItem(item);
    expect(streamNotified, isTrue);
  }

  test_performWorkItem_exceptionInTask() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor result = new ResultDescriptor('result', null);
    CaughtException exception =
        new CaughtException(new AnalysisException(), null);
    TestAnalysisTask task;
    TaskDescriptor descriptor = new TaskDescriptor(
        'task', (context, target) => task, (target) => {}, [result]);
    task = new TestAnalysisTask(context, target,
        descriptor: descriptor, exception: exception);
    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);

    analysisDriver.performWorkItem(item);
    CacheEntry targetEntry = context.getCacheEntry(item.target);
    expect(targetEntry.exception, exception);
    expect(targetEntry.getState(result), CacheState.ERROR);
  }

  test_performWorkItem_noException() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor result = new ResultDescriptor('result', null);
    TestAnalysisTask task;
    TaskDescriptor descriptor = new TaskDescriptor(
        'task', (context, target) => task, (target) => {}, [result]);
    task = new TestAnalysisTask(context, target, descriptor: descriptor);
    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);

    analysisDriver.performWorkItem(item);
    CacheEntry targetEntry = context.getCacheEntry(item.target);
    expect(targetEntry.exception, isNull);
    expect(targetEntry.getState(result), CacheState.VALID);
  }

  test_performWorkItem_preExistingException() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor result = new ResultDescriptor('result', null);
    TaskDescriptor descriptor = new TaskDescriptor(
        'task',
        (context, target) => new TestAnalysisTask(context, target),
        (target) => {},
        [result]);
    CaughtException exception =
        new CaughtException(new AnalysisException(), null);
    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
    item.exception = exception;

    analysisDriver.performWorkItem(item);
    CacheEntry targetEntry = context.getCacheEntry(item.target);
    expect(targetEntry.exception, exception);
    expect(targetEntry.getState(result), CacheState.ERROR);
  }

  test_reset() {
    ResultDescriptor inputResult = new ResultDescriptor('input', null);
    TaskDescriptor descriptor = new TaskDescriptor(
        'task',
        (context, target) => new TestAnalysisTask(context, target),
        (target) => {'one': inputResult.of(target)},
        [new ResultDescriptor('output', null)]);
    analysisDriver.currentWorkOrder = new WorkOrder(
        taskManager, new WorkItem(null, null, descriptor, null, 0, null));

    analysisDriver.reset();
    expect(analysisDriver.currentWorkOrder, isNull);
  }

  void _configureDescriptors12() {
    descriptor1 = new TaskDescriptor(
        'task1',
        (context, target) =>
            new TestAnalysisTask(context, target, descriptor: descriptor1),
        (target) => {},
        [result1]);
    taskManager.addTaskDescriptor(descriptor1);

    descriptor2 = new TaskDescriptor(
        'task2',
        (context, target) =>
            new TestAnalysisTask(context, target, descriptor: descriptor1),
        (target) => {},
        [result2]);
    taskManager.addTaskDescriptor(descriptor2);
  }

  /**
   * [complete] is `true` if the value of the result has already been computed.
   * [priorityTarget] is `true` if the target is in the list of priority
   * targets.
   * [priorityResult] is `true` if the result should only be computed for
   * priority targets.
   */
  _createWorkOrderForTarget(
      bool complete, bool priorityTarget, bool priorityResult) {
    AnalysisTarget target = new TestSource();
    ResultDescriptor<String> result =
        new ResultDescriptor<String>('result', null);
    TaskDescriptor descriptor = new TaskDescriptor(
        'task',
        (context, target) => new TestAnalysisTask(context, target),
        (target) => {},
        [result]);
    if (priorityResult) {
      taskManager.addPriorityResult(result);
    } else {
      taskManager.addGeneralResult(result);
    }
    taskManager.addTaskDescriptor(descriptor);
    if (priorityTarget) {
      context.priorityTargets.add(target);
    } else {
      context.explicitTargets.add(target);
    }
    if (complete) {
      context
          .getCacheEntry(target)
          .setValue(result, '', const <TargetedResult>[]);
    } else {
      context.getCacheEntry(target).setState(result, CacheState.INVALID);
    }

    WorkOrder workOrder =
        analysisDriver.createWorkOrderForTarget(target, priorityTarget);
    if (complete) {
      expect(workOrder, isNull);
    } else if (priorityResult) {
      expect(workOrder, priorityTarget ? isNotNull : isNull);
    } else {
      expect(workOrder, isNotNull);
    }
  }
}

@reflectiveTest
class CycleAwareDependencyWalkerTest {
  void checkGraph(Map<int, List<int>> graph, int startingNode,
      List<StronglyConnectedComponent<int>> expectedResults) {
    List<Set<int>> expectedResultsDisregardingOrder =
        expectedResults.map((component) => component.nodes.toSet()).toList();
    List<bool> expectedCycleIndicators =
        expectedResults.map((component) => component.containsCycle).toList();
    List<Set<int>> results = <Set<int>>[];
    List<bool> cycleIndicators = <bool>[];
    _TestCycleAwareDependencyWalker walker =
        new _TestCycleAwareDependencyWalker(graph, startingNode);
    while (true) {
      StronglyConnectedComponent<int> nextStronglyConnectedComponent =
          walker.getNextStronglyConnectedComponent();
      if (nextStronglyConnectedComponent == null) {
        break;
      }
      results.add(nextStronglyConnectedComponent.nodes.toSet());
      cycleIndicators.add(nextStronglyConnectedComponent.containsCycle);
      walker.evaluatedNodes.addAll(nextStronglyConnectedComponent.nodes);
    }
    expect(results, expectedResultsDisregardingOrder);
    expect(cycleIndicators, expectedCycleIndicators);
  }

  StronglyConnectedComponent<int> cycle(List<int> nodes) =>
      new StronglyConnectedComponent(nodes, true);

  StronglyConnectedComponent<int> singleton(int node) =>
      new StronglyConnectedComponent(<int>[node], false);

  void test_complex_graph() {
    checkGraph(
        {
          1: [2, 3],
          2: [3, 4],
          3: [],
          4: [3, 5],
          5: [2, 6],
          6: [3, 4]
        },
        1,
        [
          singleton(3),
          cycle([2, 4, 5, 6]),
          singleton(1)
        ]);
  }

  void test_cycle_depends_on_other_nodes() {
    checkGraph(
        {
          1: [2, 3],
          2: [4, 1],
          3: [],
          4: []
        },
        1,
        [
          singleton(4),
          singleton(3),
          cycle([1, 2])
        ]);
  }

  void test_initial_node_depends_on_cycle() {
    checkGraph(
        {
          1: [2],
          2: [3],
          3: [2]
        },
        1,
        [
          cycle([2, 3]),
          singleton(1)
        ]);
  }

  void test_simple_cycle() {
    checkGraph(
        {
          1: [2],
          2: [1]
        },
        1,
        [
          cycle([1, 2])
        ]);
  }

  void test_simple_dependency_chain() {
    checkGraph(
        {
          1: [2],
          2: []
        },
        1,
        [singleton(2), singleton(1)]);
  }

  void test_single_node() {
    checkGraph({1: []}, 1, [singleton(1)]);
  }

  void test_single_node_cycle() {
    checkGraph(
        {
          1: [1]
        },
        1,
        [
          cycle([1])
        ]);
  }
}

@reflectiveTest
class WorkItemTest extends AbstractDriverTest {
  test_buildTask_complete() {
    AnalysisTarget target = new TestSource();
    TaskDescriptor descriptor = new TaskDescriptor(
        'task',
        (context, target) => new TestAnalysisTask(context, target),
        (target) => {},
        [new ResultDescriptor('output', null)]);
    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
    AnalysisTask task = item.buildTask();
    expect(task, isNotNull);
  }

  test_buildTask_incomplete() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor inputResult = new ResultDescriptor('input', null);
    List<ResultDescriptor> outputResults = <ResultDescriptor>[
      new ResultDescriptor('output', null)
    ];
    TaskDescriptor descriptor = new TaskDescriptor(
        'task',
        (context, target) =>
            new TestAnalysisTask(context, target, results: outputResults),
        (target) => {'one': inputResult.of(target)},
        outputResults);
    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
    expect(() => item.buildTask(), throwsStateError);
  }

  test_create() {
    AnalysisTarget target = new TestSource();
    TaskDescriptor descriptor = new TaskDescriptor(
        'task', null, (target) => {}, [new ResultDescriptor('result', null)]);
    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
    expect(item, isNotNull);
    expect(item.context, context);
    expect(item.descriptor, descriptor);
    expect(item.target, target);
  }

  test_gatherInputs_aboutToComputeResult_hasResult() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor resultA = new ResultDescriptor('resultA', null);
    ResultDescriptor resultB = new ResultDescriptor('resultB', null);
    // prepare tasks
    TaskDescriptor task1 = new TaskDescriptor(
        'task',
        (context, target) =>
            new TestAnalysisTask(context, target, results: [resultA]),
        (target) => {},
        [resultA]);
    TaskDescriptor task2 = new TaskDescriptor(
        'task',
        (context, target) => new TestAnalysisTask(context, target),
        (target) => {'one': resultA.of(target)},
        [resultB]);
    taskManager.addTaskDescriptor(task1);
    taskManager.addTaskDescriptor(task2);
    // configure mocks
    context.aboutToComputeResultMap[resultA] = true;
    // gather inputs
    WorkItem item = new WorkItem(context, target, task2, null, 0, null);
    WorkItem inputItem = item.gatherInputs(taskManager, []);
    expect(inputItem, isNull);
  }

  test_gatherInputs_aboutToComputeResult_noResult() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor resultA = new ResultDescriptor('resultA', null);
    ResultDescriptor resultB = new ResultDescriptor('resultB', null);
    // prepare tasks
    TaskDescriptor task1 = new TaskDescriptor(
        'task',
        (context, target) =>
            new TestAnalysisTask(context, target, results: [resultA]),
        (target) => {},
        [resultA]);
    TaskDescriptor task2 = new TaskDescriptor(
        'task',
        (context, target) => new TestAnalysisTask(context, target),
        (target) => {'one': resultA.of(target)},
        [resultB]);
    taskManager.addTaskDescriptor(task1);
    taskManager.addTaskDescriptor(task2);
    // configure ResultProvider
    // configure mocks
    context.aboutToComputeResultMap[resultA] = false;
    // gather inputs
    WorkItem item = new WorkItem(context, target, task2, null, 0, null);
    WorkItem inputItem = item.gatherInputs(taskManager, []);
    expect(inputItem, isNotNull);
    expect(inputItem.target, target);
    expect(inputItem.descriptor, task1);
  }

  test_gatherInputs_complete() {
    AnalysisTarget target = new TestSource();
    TaskDescriptor descriptor = new TaskDescriptor(
        'task',
        (context, target) => new TestAnalysisTask(context, target),
        (target) => {},
        [new ResultDescriptor('output', null)]);
    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
    WorkItem result = item.gatherInputs(taskManager, []);
    expect(result, isNull);
    expect(item.exception, isNull);
  }

  test_gatherInputs_incomplete() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor resultA = new ResultDescriptor('resultA', null);
    ResultDescriptor resultB = new ResultDescriptor('resultB', null);
    // prepare tasks
    TaskDescriptor task1 = new TaskDescriptor(
        'task',
        (context, target) =>
            new TestAnalysisTask(context, target, results: [resultA]),
        (target) => {},
        [resultA]);
    TaskDescriptor task2 = new TaskDescriptor(
        'task',
        (context, target) => new TestAnalysisTask(context, target),
        (target) => {'one': resultA.of(target)},
        [resultB]);
    taskManager.addTaskDescriptor(task1);
    taskManager.addTaskDescriptor(task2);
    // gather inputs
    WorkItem item = new WorkItem(context, target, task2, null, 0, null);
    WorkItem inputItem = item.gatherInputs(taskManager, []);
    expect(inputItem, isNotNull);
  }

  test_gatherInputs_invalid() {
    AnalysisTarget target = new TestSource();
    ResultDescriptor inputResult = new ResultDescriptor('input', null);
    TaskDescriptor descriptor = new TaskDescriptor(
        'task',
        (context, target) => new TestAnalysisTask(context, target),
        (target) => {'one': inputResult.of(target)},
        [new ResultDescriptor('output', null)]);
    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
    WorkItem result = item.gatherInputs(taskManager, []);
    expect(result, isNull);
    expect(item.exception, isNotNull);
  }
}

@reflectiveTest
class WorkOrderTest extends EngineTestCase {
  test_create() {
    TaskManager manager = new TaskManager();
    TaskDescriptor descriptor = new TaskDescriptor(
        'task', null, (_) => {}, [new ResultDescriptor('result', null)]);
    WorkOrder order = new WorkOrder(
        manager, new WorkItem(null, null, descriptor, null, 0, null));
    expect(order, isNotNull);
    expect(order.currentItems, isNull);
    expect(order.current, isNull);
  }

  test_moveNext() {
    TaskManager manager = new TaskManager();
    TaskDescriptor descriptor = new TaskDescriptor(
        'task', null, (_) => {}, [new ResultDescriptor('result', null)]);
    WorkItem workItem = new WorkItem(null, null, descriptor, null, 0, null);
    WorkOrder order = new WorkOrder(manager, workItem);
    // "item" has no child items
    expect(order.moveNext(), isTrue);
    expect(order.current, workItem);
    // done
    expect(order.moveNext(), isFalse);
    expect(order.current, isNull);
  }
}

/**
 * A dummy [InternalAnalysisContext] that does not use [AnalysisDriver] itself,
 * but provides enough implementation for it to function.
 */
class _InternalAnalysisContextMock implements InternalAnalysisContext {
  AnalysisCache analysisCache;

  Map<ResultDescriptor, bool> aboutToComputeResultMap = {};

  @override
  final AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl();

  @override
  List<AnalysisTarget> explicitTargets = <AnalysisTarget>[];

  @override
  List<AnalysisTarget> priorityTargets = <AnalysisTarget>[];

  _InternalAnalysisContextMock() {
    analysisCache = new AnalysisCache([new UniversalCachePartition(this)]);
  }

  String get name => 'mock';

  @override
  bool aboutToComputeResult(CacheEntry entry, ResultDescriptor result) =>
      aboutToComputeResultMap[result] ?? false;

  @override
  CacheEntry getCacheEntry(AnalysisTarget target) {
    CacheEntry entry = analysisCache.get(target);
    if (entry == null) {
      entry = new CacheEntry(target);
      analysisCache.put(entry);
    }
    return entry;
  }

  @override
  noSuchMethod(Invocation invocation) {
    throw new StateError('Unexpected invocation of ${invocation.memberName}');
  }
}

/**
 * Concrete class for testing [CycleAwareDependencyWalker] behavior.
 */
class _TestCycleAwareDependencyWalker extends CycleAwareDependencyWalker<int> {
  final Map<int, List<int>> graph;

  Set<int> evaluatedNodes = new Set<int>();

  _TestCycleAwareDependencyWalker(this.graph, int startingNode)
      : super(startingNode);

  @override
  int getNextInput(int node, List<int> skipInputs) {
    for (int dependency in graph[node]) {
      if (!skipInputs.contains(dependency) &&
          !evaluatedNodes.contains(dependency)) {
        return dependency;
      }
    }
    return null;
  }
}

class _WorkManagerMock implements WorkManager {
  WorkOrderPriority nextResultPriority;

  TargetedResult nextResult;

  TargetedResult getNextResult() => nextResult;

  WorkOrderPriority getNextResultPriority() => nextResultPriority;

  @override
  noSuchMethod(Invocation invocation) {
    throw new StateError('Unexpected invocation of ${invocation.memberName}');
  }

  void resultsComputed(
      AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs) {}
}
