// Copyright (c) 2017, 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/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';

/**
 * Callback used by [FileTracker] to report to its client that files have been
 * added, changed, or removed, and therefore more analysis may be necessary.
 * [path] is the path of the file that was added, changed, or removed,
 * or `null` if multiple files were added, changed, or removed.
 */
typedef void FileTrackerChangeHook(String path);

/**
 * Maintains the file system state needed by the analysis driver, as well as
 * information about files that have changed and the impact of those changes.
 *
 * Three related sets of files are tracked: "added files" is the set of files
 * for which the client would like analysis.  "changed files" is the set of
 * files which is known to have changed, but for which we have not yet measured
 * the impact of the change.  "pending files" is the subset of "added files"
 * which might have been impacted by a change, and thus need analysis.
 *
 * Provides methods for updating the file system state in response to changes.
 */
class FileTracker {
  /**
   * Callback invoked whenever a change occurs that may require the client to
   * perform analysis.
   */
  final FileTrackerChangeHook _changeHook;

  /**
   * The logger to write performed operations and performance to.
   */
  final PerformanceLog _logger;

  /**
   * The current file system state.
   */
  final FileSystemState _fsState;

  /**
   * The set of added files.
   */
  final addedFiles = new LinkedHashSet<String>();

  /**
   * The set of files were reported as changed through [changeFile] and not
   * checked for actual changes yet.
   */
  final _changedFiles = new LinkedHashSet<String>();

  /**
   * The set of files that are currently scheduled for analysis, which were
   * reported as changed through [changeFile].
   */
  var _pendingChangedFiles = new LinkedHashSet<String>();

  /**
   * The set of files that are currently scheduled for analysis, which directly
   * import a changed file.
   */
  var _pendingImportFiles = new LinkedHashSet<String>();

  /**
   * The set of files that are currently scheduled for analysis, which have an
   * error or a warning, which might be fixed by a changed file.
   */
  var _pendingErrorFiles = new LinkedHashSet<String>();

  /**
   * The set of files that are currently scheduled for analysis, and don't
   * have any special relation with changed files.
   */
  var _pendingFiles = new LinkedHashSet<String>();

  FileTracker(this._logger, this._fsState, this._changeHook);

  /**
   * Returns the path to exactly one that needs analysis.  Throws a [StateError]
   * if no files need analysis.
   */
  String get anyPendingFile {
    if (_pendingChangedFiles.isNotEmpty) {
      return _pendingChangedFiles.first;
    }
    if (_pendingImportFiles.isNotEmpty) {
      return _pendingImportFiles.first;
    }
    if (_pendingErrorFiles.isNotEmpty) {
      return _pendingErrorFiles.first;
    }
    return _pendingFiles.first;
  }

  /**
   * Returns a boolean indicating whether there are any files that have changed,
   * but for which the impact of the changes hasn't been measured.
   */
  bool get hasChangedFiles => _changedFiles.isNotEmpty;

  /**
   * Return `true` if there are changed files that need analysis.
   */
  bool get hasPendingChangedFiles => _pendingChangedFiles.isNotEmpty;

  /**
   * Return `true` if there are files that have an error or warning, and that
   * need analysis.
   */
  bool get hasPendingErrorFiles => _pendingErrorFiles.isNotEmpty;

  /**
   * Returns a boolean indicating whether there are any files that need
   * analysis.
   */
  bool get hasPendingFiles {
    return hasPendingChangedFiles ||
        hasPendingImportFiles ||
        hasPendingErrorFiles ||
        _pendingFiles.isNotEmpty;
  }

  /**
   * Return `true` if there are files that directly import a changed file that
   * need analysis.
   */
  bool get hasPendingImportFiles => _pendingImportFiles.isNotEmpty;

  /**
   * Returns a count of how many files need analysis.
   */
  int get numberOfPendingFiles {
    return _pendingChangedFiles.length +
        _pendingImportFiles.length +
        _pendingErrorFiles.length +
        _pendingFiles.length;
  }

  /**
   * Adds the given [path] to the set of "added files".
   */
  void addFile(String path) {
    _fsState.markFileForReading(path);
    addedFiles.add(path);
    _pendingFiles.add(path);
    _changeHook(path);
  }

  /**
   * Adds the given [paths] to the set of "added files".
   */
  void addFiles(Iterable<String> paths) {
    addedFiles.addAll(paths);
    _pendingFiles.addAll(paths);
    _changeHook(null);
  }

  /**
   * Adds the given [path] to the set of "changed files".
   */
  void changeFile(String path) {
    _changedFiles.add(path);
    if (addedFiles.contains(path)) {
      _pendingChangedFiles.add(path);
    }
    _fsState.markFileForReading(path);
    _changeHook(path);
  }

  /**
   * Removes the given [path] from the set of "pending files".
   *
   * Should be called after the client has analyzed a file.
   */
  void fileWasAnalyzed(String path) {
    _pendingChangedFiles.remove(path);
    _pendingImportFiles.remove(path);
    _pendingErrorFiles.remove(path);
    _pendingFiles.remove(path);
  }

  /**
   * Returns a boolean indicating whether the given [path] points to a file that
   * requires analysis.
   */
  bool isFilePending(String path) {
    return _pendingChangedFiles.contains(path) ||
        _pendingImportFiles.contains(path) ||
        _pendingErrorFiles.contains(path) ||
        _pendingFiles.contains(path);
  }

  /**
   * Removes the given [path] from the set of "added files".
   */
  void removeFile(String path) {
    addedFiles.remove(path);
    _pendingChangedFiles.remove(path);
    _pendingImportFiles.remove(path);
    _pendingErrorFiles.remove(path);
    _pendingFiles.remove(path);
    // TODO(paulberry): removing the path from [fsState] and re-analyzing all
    // files seems extreme.
    _fsState.removeFile(path);
    _pendingFiles.addAll(addedFiles);
    _changeHook(path);
  }

  /**
   * Schedule all added files for analysis.
   */
  void scheduleAllAddedFiles() {
    _pendingFiles.addAll(addedFiles);
  }

  /**
   * Verify the API signature for the file with the given [path], and decide
   * which linked libraries should be invalidated, and files reanalyzed.
   */
  FileState verifyApiSignature(String path) {
    return _logger.run('Verify API signature of $path', () {
      bool anyApiChanged = false;
      List<FileState> files = _fsState.getFilesForPath(path);
      for (FileState file in files) {
        bool apiChanged = file.refresh();
        if (apiChanged) {
          anyApiChanged = true;
        }
      }
      if (anyApiChanged) {
        _logger.writeln('API signatures mismatch found for $path');
        // TODO(scheglov) schedule analysis of only affected files
        var pendingChangedFiles = new LinkedHashSet<String>();
        var pendingImportFiles = new LinkedHashSet<String>();
        var pendingErrorFiles = new LinkedHashSet<String>();
        var pendingFiles = new LinkedHashSet<String>();

        // Add the changed file.
        if (addedFiles.contains(path)) {
          pendingChangedFiles.add(path);
        }

        // Add files that directly import the changed file.
        for (String addedPath in addedFiles) {
          FileState addedFile = _fsState.getFileForPath(addedPath);
          for (FileState changedFile in files) {
            if (addedFile.importedFiles.contains(changedFile)) {
              pendingImportFiles.add(addedPath);
            }
          }
        }

        // Add files with errors or warnings that might be fixed.
        for (String addedPath in addedFiles) {
          FileState addedFile = _fsState.getFileForPath(addedPath);
          if (addedFile.hasErrorOrWarning) {
            pendingErrorFiles.add(addedPath);
          }
        }

        // Add all previous pending files.
        pendingChangedFiles.addAll(_pendingChangedFiles);
        pendingImportFiles.addAll(_pendingImportFiles);
        pendingErrorFiles.addAll(_pendingErrorFiles);
        pendingFiles.addAll(_pendingFiles);

        // Add all the rest.
        pendingFiles.addAll(addedFiles);

        // Replace pending files.
        _pendingChangedFiles = pendingChangedFiles;
        _pendingImportFiles = pendingImportFiles;
        _pendingErrorFiles = pendingErrorFiles;
        _pendingFiles = pendingFiles;
      }
      return files[0];
    });
  }

  /**
   * If at least one file is in the "changed files" set, determines the impact
   * of the change, updates the set of pending files, and returns `true`.
   *
   * If no files are in the "changed files" set, returns `false`.
   */
  bool verifyChangedFilesIfNeeded() {
    // Verify all changed files one at a time.
    if (_changedFiles.isNotEmpty) {
      String path = _changedFiles.first;
      _changedFiles.remove(path);
      // If the file has not been accessed yet, we either will eventually read
      // it later while analyzing one of the added files, or don't need it.
      if (_fsState.knownFilePaths.contains(path)) {
        verifyApiSignature(path);
      }
      return true;
    }
    return false;
  }
}
