// 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.test.src.task.options_work_manager_test;

import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/generated/engine.dart'
    show
        AnalysisEngine,
        AnalysisErrorInfo,
        AnalysisErrorInfoImpl,
        CacheState,
        ChangeNoticeImpl,
        InternalAnalysisContext;
import 'package:analyzer/src/generated/error.dart'
    show AnalysisError, AnalysisOptionsErrorCode;
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/task/options_work_manager.dart';
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/model.dart';
import 'package:typed_mock/typed_mock.dart';
import 'package:unittest/unittest.dart';

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

main() {
  initializeTestEnvironment();
  runReflectiveTests(OptionsWorkManagerTest);
}

@reflectiveTest
class OptionsWorkManagerTest {
  static final optionsFile = AnalysisEngine.ANALYSIS_OPTIONS_FILE;
  InternalAnalysisContext context = new _InternalAnalysisContextMock();
  AnalysisCache cache;

  OptionsWorkManager manager;

  CaughtException caughtException = new CaughtException(null, null);

  Source source1 = new TestSource('test1/$optionsFile');
  Source source2 = new TestSource('test2/$optionsFile');
  Source source3 = new TestSource('test3/$optionsFile');
  Source source4 = new TestSource('test4/$optionsFile');
  CacheEntry entry1;
  CacheEntry entry2;
  CacheEntry entry3;
  CacheEntry entry4;

  void expect_sourceQueue(List<Source> sources) {
    expect(manager.sourceQueue, unorderedEquals(sources));
  }

  void setUp() {
    cache = context.analysisCache;
    manager = new OptionsWorkManager(context);
    entry1 = context.getCacheEntry(source1);
    entry2 = context.getCacheEntry(source2);
    entry3 = context.getCacheEntry(source3);
    entry4 = context.getCacheEntry(source4);
  }

  void test_applyChange_add() {
    // add source1
    manager.applyChange([source1], [], []);
    expect_sourceQueue([source1]);
    // add source2
    manager.applyChange([source2], [], []);
    expect_sourceQueue([source1, source2]);
  }

  void test_applyChange_add_duplicate() {
    // add source1
    manager.applyChange([source1], [], []);
    expect_sourceQueue([source1]);
    // add source1 again
    manager.applyChange([source1], [], []);
    expect_sourceQueue([source1]);
  }

  void test_applyChange_change() {
    // change source1
    manager.applyChange([], [source1], []);
    expect_sourceQueue([source1]);
  }

  void test_applyChange_change_afterAdd() {
    manager.applyChange([source1, source2], [], []);
    // change source1
    manager.applyChange([], [source1], []);
    expect_sourceQueue([source1, source2]);
  }

  void test_applyChange_remove() {
    manager.applyChange([source1, source2], [], []);
    // remove source1
    manager.applyChange([], [], [source1]);
    expect_sourceQueue([source2]);
    // remove source2
    manager.applyChange([], [], [source2]);
    expect_sourceQueue([]);
    // remove source3
    manager.applyChange([], [], [source3]);
    expect_sourceQueue([]);
  }

  void test_applyPriorityTargets() {
    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
    when(context.shouldErrorsBeAnalyzed(source3)).thenReturn(true);
    manager.priorityResultQueue
        .add(new TargetedResult(source1, ANALYSIS_OPTIONS_ERRORS));
    manager.priorityResultQueue
        .add(new TargetedResult(source2, ANALYSIS_OPTIONS_ERRORS));
    // -source1 +source3
    manager.applyPriorityTargets([source2, source3]);
    expect(
        manager.priorityResultQueue,
        unorderedEquals([
          new TargetedResult(source2, ANALYSIS_OPTIONS_ERRORS),
          new TargetedResult(source3, ANALYSIS_OPTIONS_ERRORS)
        ]));
    // get next request
    TargetedResult request = manager.getNextResult();
    expect(request.target, source2);
    expect(request.result, ANALYSIS_OPTIONS_ERRORS);
  }

  void test_getErrors() {
    AnalysisError error1 = new AnalysisError(
        source1, 1, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
    AnalysisError error2 = new AnalysisError(
        source1, 2, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
    entry1
        .setValue(ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);

    List<AnalysisError> errors = manager.getErrors(source1);
    expect(errors, unorderedEquals([error1, error2]));
  }

  void test_getNextResult_hasNormal_firstIsError() {
    entry1.setErrorState(caughtException, [ANALYSIS_OPTIONS_ERRORS]);
    manager.sourceQueue.addAll([source1, source2]);
    TargetedResult request = manager.getNextResult();
    expect(request.target, source2);
    expect(request.result, ANALYSIS_OPTIONS_ERRORS);
    // source1 is out, source2 is waiting
    expect_sourceQueue([source2]);
  }

  void test_getNextResult_hasNormal_firstIsInvalid() {
    entry1.setState(ANALYSIS_OPTIONS_ERRORS, CacheState.INVALID);
    manager.sourceQueue.addAll([source1, source2]);
    TargetedResult request = manager.getNextResult();
    expect(request.target, source1);
    expect(request.result, ANALYSIS_OPTIONS_ERRORS);
    // no changes until computed
    expect_sourceQueue([source1, source2]);
  }

  void test_getNextResult_hasNormal_firstIsValid() {
    entry1.setValue(ANALYSIS_OPTIONS_ERRORS, [], []);
    manager.sourceQueue.addAll([source1, source2]);
    TargetedResult request = manager.getNextResult();
    expect(request.target, source2);
    expect(request.result, ANALYSIS_OPTIONS_ERRORS);
    // source1 is out, source2 is waiting
    expect_sourceQueue([source2]);
  }

  void test_getNextResult_hasNormalAndPriority() {
    entry1.setState(ANALYSIS_OPTIONS_ERRORS, CacheState.INVALID);
    manager.sourceQueue.addAll([source1, source2]);
    manager.addPriorityResult(source3, ANALYSIS_OPTIONS_ERRORS);

    TargetedResult request = manager.getNextResult();
    expect(request.target, source3);
    expect(request.result, ANALYSIS_OPTIONS_ERRORS);
    // no changes until computed
    expect_sourceQueue([source1, source2]);
  }

  void test_getNextResult_hasPriority() {
    manager.addPriorityResult(source1, ANALYSIS_OPTIONS_ERRORS);
    manager.addPriorityResult(source2, ANALYSIS_OPTIONS_ERRORS);
    expect(
        manager.priorityResultQueue,
        unorderedEquals([
          new TargetedResult(source1, ANALYSIS_OPTIONS_ERRORS),
          new TargetedResult(source2, ANALYSIS_OPTIONS_ERRORS)
        ]));

    TargetedResult request = manager.getNextResult();
    expect(request.target, source1);
    expect(request.result, ANALYSIS_OPTIONS_ERRORS);
    // no changes until computed
    expect(
        manager.priorityResultQueue,
        unorderedEquals([
          new TargetedResult(source1, ANALYSIS_OPTIONS_ERRORS),
          new TargetedResult(source2, ANALYSIS_OPTIONS_ERRORS)
        ]));
  }

  void test_getNextResult_nothingToDo() {
    TargetedResult request = manager.getNextResult();
    expect(request, isNull);
  }

  void test_getNextResultPriority_hasPriority() {
    manager.addPriorityResult(source1, SOURCE_KIND);
    expect(manager.getNextResultPriority(), WorkOrderPriority.PRIORITY);
  }

  void test_getNextResultPriority_hasSource() {
    manager.sourceQueue.addAll([source1]);
    expect(manager.getNextResultPriority(), WorkOrderPriority.NORMAL);
  }

  void test_getNextResultPriority_nothingToDo() {
    expect(manager.getNextResultPriority(), WorkOrderPriority.NONE);
  }

  void test_resultsComputed_errors() {
    AnalysisError error1 = new AnalysisError(
        source1, 1, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
    AnalysisError error2 = new AnalysisError(
        source1, 2, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
    LineInfo lineInfo = new LineInfo([0]);
    entry1.setValue(LINE_INFO, lineInfo, []);
    entry1
        .setValue(ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
    // RESOLVED_UNIT is ready, set errors
    manager.resultsComputed(source1, {ANALYSIS_OPTIONS_ERRORS: null});
    // all of the errors are included
    ChangeNoticeImpl notice = context.getNotice(source1);
    expect(notice.errors, unorderedEquals([error1, error2]));
    expect(notice.lineInfo, lineInfo);
  }
}

class _InternalAnalysisContextMock extends TypedMock
    implements InternalAnalysisContext {
  @override
  CachePartition privateAnalysisCachePartition;

  @override
  AnalysisCache analysisCache;

  Map<Source, ChangeNoticeImpl> _pendingNotices = <Source, ChangeNoticeImpl>{};

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

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

  @override
  AnalysisErrorInfo getErrors(Source source) {
    List<AnalysisError> errors = AnalysisError.NO_ERRORS;
    if (AnalysisEngine.isAnalysisOptionsFileName(source.shortName)) {
      errors = getCacheEntry(source).getValue(ANALYSIS_OPTIONS_ERRORS);
    }
    return new AnalysisErrorInfoImpl(
        errors, getCacheEntry(source).getValue(LINE_INFO));
  }

  @override
  ChangeNoticeImpl getNotice(Source source) =>
      _pendingNotices.putIfAbsent(source, () => new ChangeNoticeImpl(source));
}
