// Copyright (c) 2014, 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/exception/exception.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_io.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:path/path.dart' as path;

export 'package:analyzer/src/generated/source.dart';

/// Instances of the class [ExplicitSourceResolver] map URIs to files on disk
/// using a fixed mapping provided at construction time.
@deprecated
class ExplicitSourceResolver extends UriResolver {
  final Map<Uri, JavaFile> uriToFileMap;
  final Map<String, Uri> pathToUriMap;

  /// Construct an [ExplicitSourceResolver] based on the given [uriToFileMap].
  ExplicitSourceResolver(Map<Uri, JavaFile> uriToFileMap)
      : uriToFileMap = uriToFileMap,
        pathToUriMap = _computePathToUriMap(uriToFileMap);

  @override
  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
    JavaFile file = uriToFileMap[uri];
    actualUri ??= uri;
    if (file == null) {
      return null;
    } else {
      return FileBasedSource(file, actualUri);
    }
  }

  @override
  Uri restoreAbsolute(Source source) {
    return pathToUriMap[source.fullName];
  }

  /// Build the inverse mapping of [uriToSourceMap].
  static Map<String, Uri> _computePathToUriMap(
      Map<Uri, JavaFile> uriToSourceMap) {
    Map<String, Uri> pathToUriMap = <String, Uri>{};
    uriToSourceMap.forEach((Uri uri, JavaFile file) {
      pathToUriMap[file.getAbsolutePath()] = uri;
    });
    return pathToUriMap;
  }
}

/// Instances of the class `FileBasedSource` implement a source that represents
/// a file.
class FileBasedSource extends Source {
  /// A function that changes the way that files are read off of disk.
  static Function fileReadMode = (String s) => s;

  /// Map from encoded URI/filepath pair to a unique integer identifier.  This
  /// identifier is used for equality tests and hash codes.
  ///
  /// The URI and filepath are joined into a pair by separating them with an '@'
  /// character.
  static final Map<String, int> _idTable = HashMap<String, int>();

  /// The URI from which this source was originally derived.
  @override
  final Uri uri;

  /// The unique ID associated with this [FileBasedSource].
  final int id;

  /// The file represented by this source.
  final JavaFile file;

  /// The cached absolute path of this source.
  String _absolutePath;

  /// The cached encoding for this source.
  String _encoding;

  /// Initialize a newly created source object to represent the given [file]. If
  /// a [uri] is given, then it will be used as the URI from which the source
  /// was derived, otherwise a `file:` URI will be created based on the [file].
  FileBasedSource(JavaFile file, [Uri uri])
      : this.uri = uri ?? file.toURI(),
        this.file = file,
        id = _idTable.putIfAbsent(
            '${uri ?? file.toURI()}@${file.getPath()}', () => _idTable.length);

  @override
  TimestampedData<String> get contents {
    return PerformanceStatistics.io.makeCurrentWhile(() {
      return contentsFromFile;
    });
  }

  /// Get the contents and timestamp of the underlying file.
  ///
  /// Clients should consider using the method [AnalysisContext.getContents]
  /// because contexts can have local overrides of the content of a source that
  /// the source is not aware of.
  ///
  /// @return the contents of the source paired with the modification stamp of
  /// the source
  /// @throws Exception if the contents of this source could not be accessed
  /// See [contents].
  TimestampedData<String> get contentsFromFile {
    return TimestampedData<String>(
        file.lastModified(), fileReadMode(file.readAsStringSync()));
  }

  @override
  String get encoding {
    return _encoding ??= uri.toString();
  }

  @override
  String get fullName {
    return _absolutePath ??= file.getAbsolutePath();
  }

  @override
  int get hashCode => uri.hashCode;

  @override
  bool get isInSystemLibrary => uri.scheme == DartUriResolver.DART_SCHEME;

  @override
  int get modificationStamp => file.lastModified();

  @override
  String get shortName => file.getName();

  @override
  UriKind get uriKind {
    String scheme = uri.scheme;
    return UriKind.fromScheme(scheme);
  }

  @override
  bool operator ==(Object object) {
    if (object is FileBasedSource) {
      return id == object.id;
    } else if (object is Source) {
      return uri == object.uri;
    }
    return false;
  }

  @override
  bool exists() => file.isFile();

  @override
  String toString() {
    if (file == null) {
      return "<unknown source>";
    }
    return file.getAbsolutePath();
  }
}

/// Instances of the class `FileUriResolver` resolve `file` URI's.
///
/// This class is now deprecated, 'new FileUriResolver()' is equivalent to
/// 'new ResourceUriResolver(PhysicalResourceProvider.INSTANCE)'.
@deprecated
class FileUriResolver extends UriResolver {
  /// The name of the `file` scheme.
  static String FILE_SCHEME = "file";

  @override
  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
    if (!isFileUri(uri)) {
      return null;
    }
    return FileBasedSource(JavaFile.fromUri(uri), actualUri ?? uri);
  }

  @override
  Uri restoreAbsolute(Source source) {
    return Uri.file(source.fullName);
  }

  /// Return `true` if the given URI is a `file` URI.
  ///
  /// @param uri the URI being tested
  /// @return `true` if the given URI is a `file` URI
  static bool isFileUri(Uri uri) => uri.scheme == FILE_SCHEME;
}

/// Instances of interface `LocalSourcePredicate` are used to determine if the
/// given [Source] is "local" in some sense, so can be updated.
abstract class LocalSourcePredicate {
  /// Instance of [LocalSourcePredicate] that always returns `false`.
  static final LocalSourcePredicate FALSE = LocalSourcePredicate_FALSE();

  /// Instance of [LocalSourcePredicate] that always returns `true`.
  static final LocalSourcePredicate TRUE = LocalSourcePredicate_TRUE();

  /// Instance of [LocalSourcePredicate] that returns `true` for all [Source]s
  /// except of SDK.
  static final LocalSourcePredicate NOT_SDK = LocalSourcePredicate_NOT_SDK();

  /// Determines if the given [Source] is local.
  ///
  /// @param source the [Source] to analyze
  /// @return `true` if the given [Source] is local
  bool isLocal(Source source);
}

class LocalSourcePredicate_FALSE implements LocalSourcePredicate {
  @override
  bool isLocal(Source source) => false;
}

class LocalSourcePredicate_NOT_SDK implements LocalSourcePredicate {
  @override
  bool isLocal(Source source) => source.uriKind != UriKind.DART_URI;
}

class LocalSourcePredicate_TRUE implements LocalSourcePredicate {
  @override
  bool isLocal(Source source) => true;
}

/// Instances of the class `PackageUriResolver` resolve `package` URI's in the
/// context of an application.
///
/// For the purposes of sharing analysis, the path to each package under the
/// "packages" directory should be canonicalized, but to preserve relative links
/// within a package, the remainder of the path from the package directory to
/// the leaf should not.
@deprecated
class PackageUriResolver extends UriResolver {
  /// The name of the `package` scheme.
  static String PACKAGE_SCHEME = "package";

  /// Log exceptions thrown with the message "Required key not available" only
  /// once.
  static bool _CanLogRequiredKeyIoException = true;

  /// The package directories that `package` URI's are assumed to be relative
  /// to.
  final List<JavaFile> _packagesDirectories;

  /// Initialize a newly created resolver to resolve `package` URI's relative to
  /// the given package directories.
  ///
  /// @param packagesDirectories the package directories that `package` URI's
  ///          are assumed to be relative to
  PackageUriResolver(this._packagesDirectories) {
    if (_packagesDirectories.isEmpty) {
      throw ArgumentError("At least one package directory must be provided");
    }
  }

  /// If the list of package directories contains one element, return it.
  /// Otherwise raise an exception.  Intended for testing.
  String get packagesDirectory_forTesting {
    int length = _packagesDirectories.length;
    if (length != 1) {
      throw Exception('Expected 1 package directory, found $length');
    }
    return _packagesDirectories[0].getPath();
  }

  /// Answer the canonical file for the specified package.
  ///
  /// @param packagesDirectory the "packages" directory (not `null`)
  /// @param pkgName the package name (not `null`, not empty)
  /// @param relPath the path relative to the package directory (not `null`, no
  ///          leading slash, but may be empty string)
  /// @return the file (not `null`)
  JavaFile getCanonicalFile(
      JavaFile packagesDirectory, String pkgName, String relPath) {
    JavaFile pkgDir = JavaFile.relative(packagesDirectory, pkgName);
    try {
      pkgDir = pkgDir.getCanonicalFile();
    } catch (exception, stackTrace) {
      if (!exception.toString().contains("Required key not available")) {
        // TODO(39284): should this exception be silent?
        AnalysisEngine.instance.instrumentationService.logException(
            SilentException(
                "Canonical failed: $pkgDir", exception, stackTrace));
      } else if (_CanLogRequiredKeyIoException) {
        _CanLogRequiredKeyIoException = false;
        // TODO(39284): should this exception be silent?
        AnalysisEngine.instance.instrumentationService.logException(
            SilentException(
                "Canonical failed: $pkgDir", exception, stackTrace));
      }
    }
    return JavaFile.relative(pkgDir,
        relPath.replaceAll('/', String.fromCharCode(JavaFile.separatorChar)));
  }

  @override
  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
    if (!isPackageUri(uri)) {
      return null;
    }
    String path = uri.path;
    if (path == null) {
      path = uri.path;
      if (path == null) {
        return null;
      }
    }
    String pkgName;
    String relPath;
    int index = path.indexOf('/');
    if (index == -1) {
      // No slash
      pkgName = path;
      relPath = "";
    } else if (index == 0) {
      // Leading slash is invalid
      return null;
    } else {
      // <pkgName>/<relPath>
      pkgName = path.substring(0, index);
      relPath = path.substring(index + 1);
    }
    for (JavaFile packagesDirectory in _packagesDirectories) {
      JavaFile resolvedFile = JavaFile.relative(packagesDirectory, path);
      if (resolvedFile.exists()) {
        JavaFile canonicalFile =
            getCanonicalFile(packagesDirectory, pkgName, relPath);
        if (actualUri != null) {
          return FileBasedSource(canonicalFile, actualUri);
        }
        if (_isSelfReference(packagesDirectory, canonicalFile)) {
          uri = canonicalFile.toURI();
        }
        return FileBasedSource(canonicalFile, uri);
      }
    }
    return FileBasedSource(
        getCanonicalFile(_packagesDirectories[0], pkgName, relPath),
        actualUri ?? uri);
  }

  @override
  Uri restoreAbsolute(Source source) {
    String sourceUri = _toFileUri(source.fullName);
    for (JavaFile packagesDirectory in _packagesDirectories) {
      List<JavaFile> pkgFolders = packagesDirectory.listFiles();
      if (pkgFolders != null) {
        for (JavaFile pkgFolder in pkgFolders) {
          try {
            String pkgCanonicalUri = _toFileUri(pkgFolder.getCanonicalPath());
            if (sourceUri.startsWith(pkgCanonicalUri)) {
              String relPath = sourceUri.substring(pkgCanonicalUri.length);
              return Uri.parse(
                  "$PACKAGE_SCHEME:${pkgFolder.getName()}$relPath");
            }
          } catch (_) {}
        }
      }
    }
    return null;
  }

  /// @return `true` if "file" was found in "packagesDir", and it is part of
  ///         the "lib" folder of the application that contains in this
  ///         "packagesDir".
  bool _isSelfReference(JavaFile packagesDir, JavaFile file) {
    JavaFile rootDir = packagesDir.getParentFile();
    if (rootDir == null) {
      return false;
    }
    String rootPath = rootDir.getAbsolutePath();
    String filePath = file.getAbsolutePath();
    return filePath.startsWith("$rootPath/lib");
  }

  /// Convert the given file path to a "file:" URI.  On Windows, this transforms
  /// backslashes to forward slashes.
  String _toFileUri(String filePath) => path.context.toUri(filePath).toString();

  /// Return `true` if the given URI is a `package` URI.
  ///
  /// @param uri the URI being tested
  /// @return `true` if the given URI is a `package` URI
  static bool isPackageUri(Uri uri) => PACKAGE_SCHEME == uri.scheme;
}

/// Instances of the class `RelativeFileUriResolver` resolve `file` URI's.
///
/// This class is now deprecated, file URI resolution should be done with
/// ResourceUriResolver, i.e.
/// 'new ResourceUriResolver(PhysicalResourceProvider.INSTANCE)'.
@deprecated
class RelativeFileUriResolver extends UriResolver {
  /// The name of the `file` scheme.
  static String FILE_SCHEME = "file";

  /// The directories for the relatvie URI's
  final List<JavaFile> _relativeDirectories;

  /// The root directory for all the source trees
  final JavaFile _rootDirectory;

  /// Initialize a newly created resolver to resolve `file` URI's relative to
  /// the given root directory.
  RelativeFileUriResolver(this._rootDirectory, this._relativeDirectories)
      : super();

  @override
  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
    String rootPath = _rootDirectory.toURI().path;
    String uriPath = uri.path;
    if (uriPath != null && uriPath.startsWith(rootPath)) {
      String filePath = uri.path.substring(rootPath.length);
      for (JavaFile dir in _relativeDirectories) {
        JavaFile file = JavaFile.relative(dir, filePath);
        if (file.exists()) {
          return FileBasedSource(file, actualUri ?? uri);
        }
      }
    }
    return null;
  }

  /// Return `true` if the given URI is a `file` URI.
  ///
  /// @param uri the URI being tested
  /// @return `true` if the given URI is a `file` URI
  static bool isFileUri(Uri uri) => uri.scheme == FILE_SCHEME;
}
