// 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 '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/api/dart.dart';
import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/html.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_DIRECTIVES_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() ?? const <Source>[];
  }

  @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);
  }
}
