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

import 'dart:collection';

import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/generated/engine.dart'
    show AnalysisEngine, AnalysisErrorInfo, CacheState, InternalAnalysisContext;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/html.dart';
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/model.dart';

/**
 * The manager for Dart specific analysis.
 */
class DartWorkManager implements WorkManager {
  /**
   * The list of errors that are reported for raw Dart [Source]s.
   */
  static final List<ResultDescriptor<List<AnalysisError>>> _SOURCE_ERRORS =
      <ResultDescriptor<List<AnalysisError>>>[
    BUILD_DIRECTIVES_ERRORS,
    BUILD_LIBRARY_ERRORS,
    PARSE_ERRORS,
    SCAN_ERRORS
  ];

  /**
   * The list of errors that are reported for raw Dart [LibrarySpecificUnit]s.
   */
  static final List<ResultDescriptor<List<AnalysisError>>> _UNIT_ERRORS =
      <ResultDescriptor<List<AnalysisError>>>[
    HINTS,
    LINTS,
    LIBRARY_UNIT_ERRORS,
    RESOLVE_TYPE_NAMES_ERRORS,
    RESOLVE_TYPE_BOUNDS_ERRORS,
    RESOLVE_UNIT_ERRORS,
    STRONG_MODE_ERRORS,
    VARIABLE_REFERENCE_ERRORS,
    VERIFY_ERRORS
  ];

  final InternalAnalysisContext context;

  /**
   * The [TargetedResult]s that should be computed with priority.
   */
  final LinkedHashSet<TargetedResult> priorityResultQueue =
      new LinkedHashSet<TargetedResult>();

  /**
   * The sources whose kind we don't know yet.
   */
  final LinkedHashSet<Source> unknownSourceQueue = new LinkedHashSet<Source>();

  /**
   * The queue of library sources to process.
   */
  final LinkedHashSet<Source> librarySourceQueue = new LinkedHashSet<Source>();

  /**
   * A table mapping library sources to the part sources they include.
   */
  final HashMap<Source, List<Source>> libraryPartsMap =
      new HashMap<Source, List<Source>>();

  /**
   * A table mapping part sources to the library sources that include them.
   */
  final HashMap<Source, List<Source>> partLibrariesMap =
      new HashMap<Source, List<Source>>();

  /**
   * Initialize a newly created manager.
   */
  DartWorkManager(this.context) {
    context.onResultInvalidated.listen((InvalidatedResult event) {
      if (event.descriptor == LIBRARY_ERRORS_READY) {
        CacheEntry entry = event.entry;
        if (entry.explicitlyAdded &&
            entry.getValue(SOURCE_KIND) == SourceKind.LIBRARY) {
          librarySourceQueue.add(entry.target);
        }
      }
    });
  }

  /**
   * Returns the correctly typed result of `context.analysisCache`.
   */
  AnalysisCache get analysisCache => context.analysisCache;

  /**
   * The partition that contains analysis results that are not shared with other
   * contexts.
   */
  CachePartition get privateAnalysisCachePartition =>
      context.privateAnalysisCachePartition;

  /**
   * Specifies that the client want the given [result] of the given [target]
   * to be computed with priority.
   */
  void addPriorityResult(AnalysisTarget target, ResultDescriptor result) {
    priorityResultQueue.add(new TargetedResult(target, result));
  }

  @override
  void applyChange(List<Source> addedSources, List<Source> changedSources,
      List<Source> removedSources) {
    addedSources = addedSources.where(_isDartSource).toList();
    changedSources = changedSources
        .where(_isDartSource)
        .where((source) => _needsComputing(source, SOURCE_KIND))
        .toList();
    removedSources = removedSources.where(_isDartSource).toList();
    // unknown queue
    unknownSourceQueue.addAll(addedSources);
    unknownSourceQueue.addAll(changedSources);
    unknownSourceQueue.removeAll(removedSources);
    // library queue
    librarySourceQueue.removeAll(changedSources);
    librarySourceQueue.removeAll(removedSources);
    // parts in libraries
    for (Source changedSource in changedSources) {
      _onLibrarySourceChangedOrRemoved(changedSource);
    }
    for (Source removedSource in removedSources) {
      partLibrariesMap.remove(removedSource);
      _onLibrarySourceChangedOrRemoved(removedSource);
    }
  }

  @override
  void applyPriorityTargets(List<AnalysisTarget> targets) {
    // Unschedule the old targets.
    List<TargetedResult> resultsToUnschedule = <TargetedResult>[];
    for (TargetedResult result in priorityResultQueue) {
      if (result.result == LIBRARY_ERRORS_READY) {
        resultsToUnschedule.add(result);
      }
    }
    priorityResultQueue.removeAll(resultsToUnschedule);
    // Schedule new targets.
    for (AnalysisTarget target in targets) {
      if (_isDartSource(target)) {
        SourceKind sourceKind = analysisCache.getValue(target, SOURCE_KIND);
        if (sourceKind == SourceKind.UNKNOWN) {
          addPriorityResult(target, SOURCE_KIND);
        } else if (sourceKind == SourceKind.LIBRARY) {
          _schedulePriorityLibrarySourceAnalysis(target);
        } else if (sourceKind == SourceKind.PART) {
          List<Source> libraries = context.getLibrariesContaining(target);
          for (Source library in libraries) {
            addPriorityResult(library, LIBRARY_ERRORS_READY);
          }
        }
      }
    }
  }

  @override
  List<AnalysisError> getErrors(Source source) {
    if (!_isDartSource(source) && source is! DartScript) {
      return AnalysisError.NO_ERRORS;
    }
    // If analysis is finished, use all the errors.
    if (analysisCache.getState(source, DART_ERRORS) == CacheState.VALID) {
      return analysisCache.getValue(source, DART_ERRORS);
    }
    // If analysis is in progress, combine all known partial results.
    List<AnalysisError> errors = <AnalysisError>[];
    for (ResultDescriptor<List<AnalysisError>> descriptor in _SOURCE_ERRORS) {
      errors.addAll(analysisCache.getValue(source, descriptor));
    }
    for (Source library in context.getLibrariesContaining(source)) {
      LibrarySpecificUnit unit = new LibrarySpecificUnit(library, source);
      for (ResultDescriptor<List<AnalysisError>> descriptor in _UNIT_ERRORS) {
        errors.addAll(analysisCache.getValue(unit, descriptor));
      }
    }
    return errors;
  }

  /**
   * Returns libraries containing the given [part].
   * Maybe empty, but not null.
   */
  List<Source> getLibrariesContainingPart(Source part) {
    if (part.isInSystemLibrary) {
      DartWorkManager sdkDartWorkManager = _getSdkDartWorkManager();
      if (sdkDartWorkManager != this) {
        return sdkDartWorkManager.getLibrariesContainingPart(part);
      }
    }
    List<Source> libraries = partLibrariesMap[part];
    libraries ??= _getLibrariesContainingPartFromResultProvider(part);
    return libraries?.toList() ?? Source.EMPTY_LIST;
  }

  @override
  TargetedResult getNextResult() {
    // Try to find a priority result to compute.
    while (priorityResultQueue.isNotEmpty) {
      TargetedResult result = priorityResultQueue.first;
      if (!_needsComputing(result.target, result.result)) {
        priorityResultQueue.remove(result);
        continue;
      }
      return result;
    }
    // Try to find a new library to analyze.
    while (librarySourceQueue.isNotEmpty) {
      Source librarySource = librarySourceQueue.first;
      // Maybe done with this library.
      if (!_needsComputing(librarySource, LIBRARY_ERRORS_READY)) {
        librarySourceQueue.remove(librarySource);
        continue;
      }
      // Analyze this library.
      return new TargetedResult(librarySource, LIBRARY_ERRORS_READY);
    }
    // No libraries in the queue, check whether there are sources to organize.
    while (unknownSourceQueue.isNotEmpty) {
      Source source = unknownSourceQueue.first;
      // Maybe done with this source.
      if (!_needsComputing(source, SOURCE_KIND)) {
        unknownSourceQueue.remove(source);
        continue;
      }
      // Compute the kind of this source.
      return new TargetedResult(source, SOURCE_KIND);
    }
    // TODO(scheglov) Report errors for parts that remained in the queue after
    // all libraries had been processed.
    // No results to compute.
    return null;
  }

  @override
  WorkOrderPriority getNextResultPriority() {
    if (priorityResultQueue.isNotEmpty) {
      return WorkOrderPriority.PRIORITY;
    }
    if (unknownSourceQueue.isNotEmpty || librarySourceQueue.isNotEmpty) {
      return WorkOrderPriority.NORMAL;
    }
    return WorkOrderPriority.NONE;
  }

  /**
   * Notifies the manager about analysis options changes.
   */
  void onAnalysisOptionsChanged() {
    _invalidateAllLocalResolutionInformation(false);
  }

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

  @override
  void resultsComputed(
      AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs) {
    bool isDartSource = _isDartSource(target);
    // Route SDK outputs to the SDK WorkManager.
    if (isDartSource && target.source.isInSystemLibrary) {
      DartWorkManager sdkWorkManager = _getSdkDartWorkManager();
      if (sdkWorkManager != this) {
        sdkWorkManager.resultsComputed(target, outputs);
        return;
      }
    }
    // Organize sources.
    bool isDartLibrarySource = false;
    if (isDartSource) {
      Source source = target;
      SourceKind kind = outputs[SOURCE_KIND];
      if (kind != null) {
        unknownSourceQueue.remove(source);
        if (kind == SourceKind.LIBRARY) {
          isDartLibrarySource = true;
          if (context.prioritySources.contains(source)) {
            _schedulePriorityLibrarySourceAnalysis(source);
          } else {
            bool needErrors = _shouldErrorsBeComputed(source);
            if (needErrors) {
              librarySourceQueue.add(target);
            }
          }
        }
      }
    }
    // Update parts in libraries.
    if (isDartLibrarySource) {
      Source library = target;
      List<Source> includedParts = outputs[INCLUDED_PARTS] as List<Source>;
      if (includedParts != null) {
        libraryPartsMap[library] = includedParts;
        for (Source part in includedParts) {
          List<Source> libraries =
              partLibrariesMap.putIfAbsent(part, () => <Source>[]);
          if (!libraries.contains(library)) {
            libraries.add(library);
            _invalidateContainingLibraries(part);
          }
        }
      }
    }
    // Update notice.
    if (isDartSource) {
      bool shouldSetErrors = false;
      outputs.forEach((ResultDescriptor descriptor, value) {
        if (descriptor == PARSED_UNIT && value != null) {
          context.getNotice(target).parsedDartUnit = value;
          shouldSetErrors = true;
        }
        if (descriptor == DART_ERRORS) {
          shouldSetErrors = true;
        }
      });
      if (shouldSetErrors) {
        AnalysisErrorInfo info = context.getErrors(target);
        context.getNotice(target).setErrors(info.errors, info.lineInfo);
      }
    }
    if (target is LibrarySpecificUnit) {
      Source source = target.source;
      bool shouldSetErrors = false;
      outputs.forEach((ResultDescriptor descriptor, value) {
        if (descriptor == RESOLVED_UNIT && value != null) {
          context.getNotice(source).resolvedDartUnit = value;
          shouldSetErrors = true;
        }
      });
      if (shouldSetErrors) {
        AnalysisErrorInfo info = context.getErrors(source);
        context.getNotice(source).setErrors(info.errors, info.lineInfo);
      }
    }
  }

  /**
   * The given unit was incrementally resolved. Some of its error results might
   * have been invalidated, so we schedule it for computing errors.
   */
  void unitIncrementallyResolved(Source librarySource, Source unitSource) {
    librarySourceQueue.add(librarySource);
  }

  /**
   * Ask the [context]'s result provider for [CONTAINING_LIBRARIES].
   * Return the list of containing libraries, or `null` if unknown.
   */
  List<Source> _getLibrariesContainingPartFromResultProvider(Source part) {
    CacheEntry cacheEntry = context.getCacheEntry(part);
    bool knows = context.aboutToComputeResult(cacheEntry, CONTAINING_LIBRARIES);
    if (knows) {
      return cacheEntry.getValue(CONTAINING_LIBRARIES);
    }
    return null;
  }

  /**
   * Return the SDK [DartWorkManager] or this one.
   */
  DartWorkManager _getSdkDartWorkManager() {
    SourceFactory sourceFactory = context.sourceFactory;
    InternalAnalysisContext sdkContext = sourceFactory.dartSdk.context;
    if (sdkContext != context) {
      for (WorkManager workManager in sdkContext.workManagers) {
        if (workManager is DartWorkManager) {
          return workManager;
        }
      }
    }
    return this;
  }

  /**
   * Invalidate all of the resolution results computed by this context. The flag
   * [invalidateUris] should be `true` if the cached results of converting URIs
   * to source files should also be invalidated.
   */
  void _invalidateAllLocalResolutionInformation(bool invalidateUris) {
    CachePartition partition = privateAnalysisCachePartition;
    // Prepare targets and values to invalidate.
    List<Source> dartSources = <Source>[];
    List<LibrarySpecificUnit> unitTargets = <LibrarySpecificUnit>[];
    MapIterator<AnalysisTarget, CacheEntry> iterator = partition.iterator();
    while (iterator.moveNext()) {
      AnalysisTarget target = iterator.key;
      // Optionally gather Dart sources to invalidate URIs resolution.
      if (invalidateUris && _isDartSource(target)) {
        dartSources.add(target);
      }
      // LibrarySpecificUnit(s) are roots of Dart resolution.
      // When one is invalidated, invalidation is propagated to all resolution.
      if (target is LibrarySpecificUnit) {
        unitTargets.add(target);
        Source library = target.library;
        if (context.exists(library)) {
          CacheEntry entry = iterator.value;
          if (entry.explicitlyAdded) {
            librarySourceQueue.add(library);
          }
        }
      }
    }
    // Invalidate targets and values.
    unitTargets.forEach(partition.remove);
    for (Source dartSource in dartSources) {
      CacheEntry entry = partition.get(dartSource);
      if (entry != null) {
        // TODO(scheglov) we invalidate too much.
        // Would be nice to invalidate just URLs resolution.
        entry.setState(PARSED_UNIT, CacheState.INVALID);
        entry.setState(IMPORTED_LIBRARIES, CacheState.INVALID);
        entry.setState(EXPLICITLY_IMPORTED_LIBRARIES, CacheState.INVALID);
        entry.setState(EXPORTED_LIBRARIES, CacheState.INVALID);
        entry.setState(INCLUDED_PARTS, CacheState.INVALID);
        entry.setState(LIBRARY_SPECIFIC_UNITS, CacheState.INVALID);
        entry.setState(UNITS, CacheState.INVALID);
      }
    }
  }

  /**
   * Invalidate  [CONTAINING_LIBRARIES] for the given [source].
   * [CONTAINING_LIBRARIES] does not have dependencies, so we manage it here.
   * The [source] may be a part, or a library whose contents is updated so
   * will be a part.
   */
  void _invalidateContainingLibraries(Source source) {
    CacheEntry entry = analysisCache.get(source);
    if (entry != null) {
      entry.setState(CONTAINING_LIBRARIES, CacheState.INVALID);
    }
  }

  /**
   * Returns `true` if the given [result] of the given [target] needs
   * computing, i.e. it is not in the valid and not in the error state.
   */
  bool _needsComputing(AnalysisTarget target, ResultDescriptor result) {
    CacheState state = analysisCache.getState(target, result);
    return state != CacheState.VALID && state != CacheState.ERROR;
  }

  /**
   * The given [library] source was changed or removed.
   * Update [libraryPartsMap] and [partLibrariesMap].
   */
  void _onLibrarySourceChangedOrRemoved(Source library) {
    List<Source> parts = libraryPartsMap.remove(library);
    if (parts != null) {
      for (Source part in parts) {
        List<Source> libraries = partLibrariesMap[part];
        if (libraries != null) {
          libraries.remove(library);
          _invalidateContainingLibraries(part);
        }
      }
    }
    _invalidateContainingLibraries(library);
  }

  /**
   * Schedule computing [RESOLVED_UNIT] for the given [librarySource].
   * If errors should be computed, then schedule [LIBRARY_ERRORS_READY] instead,
   * it also computes [RESOLVED_UNIT] in process.
   */
  void _schedulePriorityLibrarySourceAnalysis(Source librarySource) {
    bool needErrors = _shouldErrorsBeComputed(librarySource);
    if (needErrors) {
      addPriorityResult(librarySource, LIBRARY_ERRORS_READY);
    } else {
      var target = new LibrarySpecificUnit(librarySource, librarySource);
      addPriorityResult(target, RESOLVED_UNIT);
    }
  }

  bool _shouldErrorsBeComputed(Source source) =>
      context.shouldErrorsBeAnalyzed(source);

  static bool _isDartSource(AnalysisTarget target) {
    return target is Source && AnalysisEngine.isDartFileName(target.fullName);
  }
}
