// 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 source.optimizing_pub_package_map_provider;

import 'dart:core' hide Resource;

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/source/package_map_provider.dart';
import 'package:analyzer/source/pub_package_map_provider.dart';
import 'package:analyzer/src/generated/sdk_io.dart';

/**
 * Extension of [PackageMapInfo] that tracks the modification timestamps of
 * pub dependencies.  This allows the analysis server to avoid making redundant
 * calls to "pub list" when nothing has changed.
 */
class OptimizingPubPackageMapInfo extends PackageMapInfo {
  /**
   * Map from file path to the file's modification timestamp prior to running
   * "pub list".  Since the set of dependencies is not always known prior to
   * running "pub list", some or all of the dependencies may be missing from
   * this map.
   */
  final Map<String, int> modificationTimes;

  OptimizingPubPackageMapInfo(Map<String, List<Folder>> packageMap,
      Set<String> dependencies, this.modificationTimes)
      : super(packageMap, dependencies);

  /**
   * Return `true` if the given [path] is listed as a dependency, and we cannot
   * prove using modification timestamps that it is unchanged.
   * [resourceProvider] is used (if necessary) to read the [path]'s
   * modification time.
   */
  bool isChangedDependency(String path, ResourceProvider resourceProvider) {
    if (!dependencies.contains(path)) {
      // Path is not a dependency.
      return false;
    }
    int lastModificationTime = modificationTimes[path];
    if (lastModificationTime != null) {
      Resource resource = resourceProvider.getResource(path);
      if (resource is File) {
        try {
          if (resource.modificationStamp == lastModificationTime) {
            // Path is a dependency, but it hasn't changed since the last run
            // of "pub list".
            return false;
          }
        } on FileSystemException {
          // Path is a dependency, but we can't read its timestamp.  Assume
          // it's changed to be safe.
        }
      }
    }
    // Path is a dependency, and we couldn't prove that it hadn't changed.
    // Assume it's changed to be safe.
    return true;
  }
}

/**
 * Extension of [PubPackageMapProvider] that outputs additional information to
 * allow the analysis server to avoid making redundant calls to "pub list" when
 * nothing has changed.
 */
class OptimizingPubPackageMapProvider extends PubPackageMapProvider {
  OptimizingPubPackageMapProvider(
      ResourceProvider resourceProvider, DirectoryBasedDartSdk sdk, [RunPubList runPubList])
      : super(resourceProvider, sdk, runPubList);

  /**
   * Compute a package map for the given folder by executing "pub list".  If
   * [previousInfo] is provided, it is used as a guess of which files the
   * package map is likely to depend on; the modification times of those files
   * are captured prior to executing "pub list" so that they can be used to
   * avoid making redundant calls to "pub list" in the future.
   *
   * Also, in the case where dependencies can't be determined because of an
   * error, the dependencies from [previousInfo] will be preserved.
   */
  OptimizingPubPackageMapInfo computePackageMap(Folder folder,
      [OptimizingPubPackageMapInfo previousInfo]) {
    // Prior to running "pub list", read the modification timestamps of all of
    // the old dependencies (if known).
    Map<String, int> modificationTimes = <String, int>{};
    if (previousInfo != null) {
      for (String path in previousInfo.dependencies) {
        Resource resource = resourceProvider.getResource(path);
        if (resource is File) {
          try {
            modificationTimes[path] = resource.modificationStamp;
          } on FileSystemException {
            // File no longer exists.  Don't record a timestamp for it; this
            // will ensure that if the file reappears, we will re-run "pub
            // list" regardless of the timestamp it reappears with.
          }
        }
      }
    }

    // Try running "pub list".
    PackageMapInfo info = super.computePackageMap(folder);
    if (info == null) {
      // Computing the package map resulted in an error.  Merge the old
      // dependencies with the new ones, if possible.
      info = super.computePackageMapError(folder);
      if (previousInfo != null) {
        info.dependencies.addAll(previousInfo.dependencies);
      }
    }

    // Discard any elements of modificationTimes that are no longer
    // dependencies.
    if (previousInfo != null) {
      for (String dependency
          in previousInfo.dependencies.difference(info.dependencies)) {
        modificationTimes.remove(dependency);
      }
    }

    // Bundle the modificationTimes with the other info.
    return new OptimizingPubPackageMapInfo(
        info.packageMap, info.dependencies, modificationTimes);
  }

  @override
  PackageMapInfo computePackageMapError(Folder folder) {
    // Return null to indicate to our override of computePackageMap that there
    // was an error, so it can compute dependencies correctly.
    return null;
  }
}
