// Copyright (c) 2016, 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:async';
import 'dart:collection';

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/util/uri.dart';
import 'package:analyzer/src/workspace/bazel_watcher.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:collection/collection.dart';
import 'package:path/path.dart' as path;
import 'package:pub_semver/pub_semver.dart';

/// Instances of the class `BazelFileUriResolver` resolve `file` URI's by first
/// resolving file uri's in the expected way, and then by looking in the
/// corresponding generated directories.
class BazelFileUriResolver extends ResourceUriResolver {
  final BazelWorkspace workspace;

  BazelFileUriResolver(this.workspace) : super(workspace.provider);

  @override
  Uri pathToUri(String path) {
    var pathContext = workspace.provider.pathContext;
    for (var genRoot in [
      ...workspace.binPaths,
      workspace.genfiles,
      workspace.readonly,
    ]) {
      if (genRoot != null && pathContext.isWithin(genRoot, path)) {
        String relative = pathContext.relative(path, from: genRoot);
        var writablePath = pathContext.join(workspace.root, relative);
        return pathContext.toUri(writablePath);
      }
    }
    return workspace.provider.pathContext.toUri(path);
  }

  @override
  Source? resolveAbsolute(Uri uri) {
    if (!ResourceUriResolver.isFileUri(uri)) {
      return null;
    }
    String filePath = fileUriToNormalizedPath(provider.pathContext, uri);
    var file = workspace.findFile(filePath);
    if (file != null) {
      return file.createSource(uri);
    }
    return null;
  }
}

/// The [UriResolver] that can resolve `package` URIs in [BazelWorkspace].
class BazelPackageUriResolver extends UriResolver {
  final BazelWorkspace _workspace;
  final path.Context _context;

  /// The cache of absolute [Uri]s to [Source]s mappings.
  final Map<Uri, Source> _sourceCache = HashMap<Uri, Source>();

  BazelPackageUriResolver(BazelWorkspace workspace)
      : _workspace = workspace,
        _context = workspace.provider.pathContext;

  @override
  Uri? pathToUri(String path) {
    // Search in each root.
    for (var root in [
      ..._workspace.binPaths,
      _workspace.genfiles,
      _workspace.readonly,
      _workspace.root
    ]) {
      var uriParts = _restoreUriParts(root, path);
      if (uriParts != null) {
        return Uri.parse('package:${uriParts[0]}/${uriParts[1]}');
      }
    }

    return null;
  }

  @override
  Source? resolveAbsolute(Uri uri) {
    var source = _sourceCache[uri];
    if (source == null) {
      source = _resolveAbsolute(uri);
      if (source != null) {
        _sourceCache[uri] = source;
      }
    }
    return source;
  }

  Source? _resolveAbsolute(Uri uri) {
    if (uri.isScheme('file')) {
      var path = fileUriToNormalizedPath(_context, uri);
      var pathRelativeToRoot = _workspace._relativeToRoot(path);
      if (pathRelativeToRoot == null) return null;
      var fullFilePath = _context.join(_workspace.root, pathRelativeToRoot);
      var file = _workspace.findFile(fullFilePath);
      return file?.createSource(uri);
    }
    if (!uri.isScheme('package')) {
      return null;
    }
    String uriPath = Uri.decodeComponent(uri.path);
    int slash = uriPath.indexOf('/');

    // If the path either starts with a slash or has no slash, it is invalid.
    if (slash < 1) {
      return null;
    }

    if (uriPath.contains('//') || uriPath.contains('..')) {
      return null;
    }

    String packageName = uriPath.substring(0, slash);

    String fileUriPart = uriPath.substring(slash + 1);
    if (fileUriPart.isEmpty) {
      return null;
    }

    String filePath = fileUriPart.replaceAll('/', _context.separator);

    if (!packageName.contains('.')) {
      String fullFilePath = _context.join(
          _workspace.root, 'third_party', 'dart', packageName, 'lib', filePath);
      var file = _workspace.findFile(fullFilePath);
      return file?.createSource(uri);
    } else {
      String packagePath = packageName.replaceAll('.', _context.separator);
      String fullFilePath =
          _context.join(_workspace.root, packagePath, 'lib', filePath);
      var file = _workspace.findFile(fullFilePath);
      return file?.createSource(uri);
    }
  }

  /// Restore [filePath] to its 'package:' URI parts.
  ///
  /// Returns `null` if [root] is null or if [filePath] is not within [root].
  List<String>? _restoreUriParts(String? root, String filePath) {
    path.Context context = _workspace.provider.pathContext;
    if (root != null && context.isWithin(root, filePath)) {
      String relative = context.relative(filePath, from: root);
      List<String> components = context.split(relative);
      if (components.length > 4 &&
          components[0] == 'third_party' &&
          components[1] == 'dart' &&
          components[3] == 'lib') {
        String packageName = components[2];
        String pathInLib = components.skip(4).join('/');
        return [packageName, pathInLib];
      } else {
        for (int i = components.length - 2; i >= 2; i--) {
          String component = components[i];
          if (component == 'lib') {
            String packageName = components.getRange(0, i).join('.');
            String pathInLib = components.skip(i + 1).join('/');
            return [packageName, pathInLib];
          }
        }
      }
    }
    return null;
  }
}

/// Information about a Bazel workspace.
class BazelWorkspace extends Workspace
    implements WorkspaceWithDefaultAnalysisOptions {
  static const String _WORKSPACE = 'WORKSPACE';
  static const String _READONLY = 'READONLY';

  /// The name of the file that identifies a set of Bazel Targets.
  ///
  /// For Dart package purposes, a BUILD file identifies a package.
  static const String _buildFileName = 'BUILD';

  /// Default prefix for "-genfiles" and "-bin" that will be assumed if no build
  /// output symlinks are found.
  static const defaultSymlinkPrefix = 'bazel';

  final ResourceProvider provider;

  /// The absolute workspace root path.
  ///
  /// It contains the `WORKSPACE` file or its parent contains the `READONLY`
  /// folder.
  @override
  final String root;

  /// Either `blaze` or `bazel`.
  final String symlinkPrefix;

  /// The absolute path to the optional read only workspace root, in the
  /// `READONLY` folder if a git-based workspace, or `null`.
  final String? readonly;

  /// The absolute paths to all `bazel-bin` folders.
  ///
  /// In practice, there is usually one "bin" path, and sometimes there are two,
  /// on distributed build systems. It is very rare to have more than two.
  final List<String> binPaths;

  /// The absolute path to the `bazel-genfiles` folder.
  final String genfiles;

  /// Sometimes `BUILD` files are not preserved, and `xyz.packages` files
  /// are created instead. But looking for them is expensive, so we want
  /// to avoid this in cases when `BUILD` files are always available.
  final bool _lookForBuildFileSubstitutes;

  /// The language version for this workspace, `null` if cannot be read.
  final Version? _languageVersion;

  /// The cache of packages. The key is the directory path, the value is
  /// the corresponding package.
  final Map<String, BazelWorkspacePackage> _directoryToPackage = {};

  final _bazelCandidateFiles = StreamController<BazelSearchInfo>.broadcast();

  BazelWorkspace._(
    this.provider,
    this.root,
    this.symlinkPrefix,
    this.readonly,
    this.binPaths,
    this.genfiles, {
    required bool lookForBuildFileSubstitutes,
  })  : _lookForBuildFileSubstitutes = lookForBuildFileSubstitutes,
        _languageVersion = _readLanguageVersion(provider, root);

  /// Stream of files that we tried to find along with their potential or actual
  /// paths.
  Stream<BazelSearchInfo> get bazelCandidateFiles =>
      _bazelCandidateFiles.stream;

  @override
  bool get isBazel => true;

  @override
  UriResolver get packageUriResolver => BazelPackageUriResolver(this);

  @override
  SourceFactory createSourceFactory(
    DartSdk? sdk,
    SummaryDataStore? summaryData,
  ) {
    List<UriResolver> resolvers = <UriResolver>[];
    if (sdk != null) {
      resolvers.add(DartUriResolver(sdk));
    }
    resolvers.add(packageUriResolver);
    resolvers.add(BazelFileUriResolver(this));
    if (summaryData != null) {
      resolvers.add(InSummaryUriResolver(summaryData));
    }
    return SourceFactory(resolvers);
  }

  /// Return the file with the given [absolutePath], looking first into
  /// directories for generated files: `bazel-bin` and `bazel-genfiles`, and
  /// then into the workspace root. The file in the workspace root is returned
  /// even if it does not exist. Return `null` if the given [absolutePath] is
  /// not in the workspace [root].
  File? findFile(String absolutePath) {
    path.Context context = provider.pathContext;
    try {
      String relative = context.relative(absolutePath, from: root);
      if (relative == '.') {
        return null;
      }
      // First check genfiles and bin directories. Note that we always use the
      // symlinks and not the [binPaths] or [genfiles] to make sure we use the
      // files corresponding to the most recent build configuration and get
      // consistent view of all the generated files.
      var generatedCandidates = [
        '$symlinkPrefix-genfiles',
        '$symlinkPrefix-bin'
      ].map((prefix) => context.join(root, context.join(prefix, relative)));
      for (var path in generatedCandidates) {
        File file = provider.getFile(path);
        if (file.exists) {
          _bazelCandidateFiles
              .add(BazelSearchInfo(relative, generatedCandidates.toList()));
          return file;
        }
      }
      // Writable
      File writableFile = provider.getFile(absolutePath);
      if (writableFile.exists) {
        return writableFile;
      }
      // READONLY
      final readonly = this.readonly;
      if (readonly != null) {
        File file = provider.getFile(context.join(readonly, relative));
        if (file.exists) {
          return file;
        }
      }
      // If we couldn't find the file, assume that it has not yet been
      // generated, so send an event with all the paths that we tried.
      _bazelCandidateFiles
          .add(BazelSearchInfo(relative, generatedCandidates.toList()));
      // Not generated, return the default one.
      return writableFile;
    } catch (_) {
      return null;
    }
  }

  @override
  BazelWorkspacePackage? findPackageFor(String filePath) {
    path.Context context = provider.pathContext;
    var directoryPath = context.dirname(filePath);

    var cachedPackage = _directoryToPackage[directoryPath];
    if (cachedPackage != null) {
      return cachedPackage;
    }

    if (!context.isWithin(root, directoryPath)) {
      return null;
    }

    // Handle files which are given with their location in "bazel-bin", etc.
    // This does not typically happen during usual analysis, but it still could,
    // and it can come up in tests.
    for (var binPath in [genfiles, ...binPaths]) {
      if (context.isWithin(binPath, directoryPath)) {
        return findPackageFor(
            context.join(root, context.relative(filePath, from: binPath)));
      }
    }

    /// Return the package rooted at [folder].
    BazelWorkspacePackage? packageRootedAt(Folder folder) {
      var uriParts = (packageUriResolver as BazelPackageUriResolver)
          ._restoreUriParts(root, '${folder.path}/lib/__fake__.dart');
      String? packageName;
      if (uriParts != null && uriParts.isNotEmpty) {
        packageName = uriParts[0];
      }
      // TODO(srawlins): If [packageName] could not be derived from [uriParts],
      //  I imagine this should throw.
      if (packageName == null) {
        return null;
      }
      var package = BazelWorkspacePackage(packageName, folder.path, this);
      _directoryToPackage[directoryPath] = package;
      return package;
    }

    var startFolder = provider.getFolder(directoryPath);
    for (var folder in startFolder.withAncestors) {
      if (folder.path.length < root.length) {
        // We've walked up outside of [root], so [path] is definitely not
        // defined in any package in this workspace.
        return null;
      }

      if (folder.getChildAssumingFile(_buildFileName).exists) {
        // Found the BUILD file, denoting a Dart package.
        return packageRootedAt(folder);
      }

      if (_hasBuildFileSubstitute(folder)) {
        return packageRootedAt(folder);
      }
    }

    return null;
  }

  /// In some distributed build environments, BUILD files are not preserved.
  /// We can still look for a ".packages" file in order to determine a
  /// package's root. A ".packages" file found in [folder]'s sister path
  /// under a "bin" path among [binPaths] denotes a Dart package.
  ///
  /// For example, if the [root] of this BazelWorkspace is
  /// "/build/work/abc123/workspace" with two "bin" folders,
  /// "/build/work/abc123/workspace/blaze-out/host/bin/" and
  /// "/build/work/abc123/workspace/blaze-out/k8-opt/bin/", and [folder]
  /// is at "/build/work/abc123/workspace/foo/bar", then we  must look for a
  /// file ending in ".packages" in the folders
  /// "/build/work/abc123/workspace/blaze-out/host/bin/foo/bar" and
  /// "/build/work/abc123/workspace/blaze-out/k8-opt/bin/foo/bar".
  bool _hasBuildFileSubstitute(Folder folder) {
    if (!_lookForBuildFileSubstitutes) {
      return false;
    }

    path.Context context = provider.pathContext;

    // [folder]'s path, relative to [root]. For example, "foo/bar".
    String relative = context.relative(folder.path, from: root);

    for (String bin in binPaths) {
      Folder binChild =
          provider.getFolder(context.normalize(context.join(bin, relative)));
      if (binChild.exists &&
          binChild.getChildren().any((c) => c.path.endsWith('.packages'))) {
        // [folder]'s sister folder within [bin] contains a ".packages" file.
        return true;
      }
    }

    return false;
  }

  String? _relativeToRoot(String p) {
    path.Context context = provider.pathContext;
    // genfiles
    if (context.isWithin(genfiles, p)) {
      return context.relative(p, from: genfiles);
    }
    // bin
    for (String bin in binPaths) {
      if (context.isWithin(bin, p)) {
        return context.relative(p, from: bin);
      }
    }
    // READONLY
    final readonly = this.readonly;
    if (readonly != null) {
      if (context.isWithin(readonly, p)) {
        return context.relative(p, from: readonly);
      }
    }
    // Not generated
    if (context.isWithin(root, p)) {
      return context.relative(p, from: root);
    }
    // Failed reverse lookup
    return null;
  }

  /// Find the Bazel workspace that contains the given [filePath].
  ///
  /// This method walks up the file system from [filePath], looking for various
  /// "marker" files which indicate a Bazel workspace.
  ///
  /// At each folder _f_ with parent _p_, starting with [filePath]:
  ///
  /// * If _f_ has a sibling folder named "READONLY", and that folder has a
  ///   child folder with the same name as _f_, then a BazelWorkspace rooted at
  ///   _f_ is returned.
  /// * If _f_ has a child folder named "blaze-out" or "bazel-out", then a
  ///   BazelWorkspace rooted at _f_ is returned.
  /// * If _f_ has a child file named "WORKSPACE", then a BazelWorkspace rooted
  ///   at _f_ is returned.
  static BazelWorkspace? find(
    ResourceProvider provider,
    String filePath, {
    bool lookForBuildFileSubstitutes = true,
  }) {
    var context = provider.pathContext;
    var startFolder = provider.getFolder(filePath);
    for (var folder in startFolder.withAncestors) {
      var parent = folder.parent;

      // Found the READONLY folder, might be a git-based workspace.
      Folder readonlyFolder = parent.getChildAssumingFolder(_READONLY);
      if (readonlyFolder.exists) {
        String root = folder.path;
        String readonlyRoot =
            context.join(readonlyFolder.path, folder.shortName);
        if (provider.getFolder(readonlyRoot).exists) {
          var binPaths = _findBinFolderPaths(folder);
          String symlinkPrefix =
              _findSymlinkPrefix(provider, root, binPaths: binPaths);
          binPaths = binPaths..add(context.join(root, '$symlinkPrefix-bin'));
          return BazelWorkspace._(provider, root, symlinkPrefix, readonlyRoot,
              binPaths, context.join(root, '$symlinkPrefix-genfiles'),
              lookForBuildFileSubstitutes: lookForBuildFileSubstitutes);
        }
      }

      if (_firstExistingFolder(parent, ['blaze-out', 'bazel-out']) != null) {
        // Found the "out" folder; must be a bazel workspace.
        String root = parent.path;
        var binPaths = _findBinFolderPaths(parent);
        String symlinkPrefix =
            _findSymlinkPrefix(provider, root, binPaths: binPaths);
        binPaths = binPaths..add(context.join(root, '$symlinkPrefix-bin'));
        return BazelWorkspace._(
            provider,
            root,
            symlinkPrefix,
            null /* readonly */,
            binPaths,
            context.join(root, '$symlinkPrefix-genfiles'),
            lookForBuildFileSubstitutes: lookForBuildFileSubstitutes);
      }

      // Found the WORKSPACE file, must be a non-git workspace.
      if (folder.getChildAssumingFile(_WORKSPACE).exists) {
        String root = folder.path;
        var binPaths = _findBinFolderPaths(folder);
        String symlinkPrefix =
            _findSymlinkPrefix(provider, root, binPaths: binPaths);
        binPaths = binPaths..add(context.join(root, '$symlinkPrefix-bin'));
        return BazelWorkspace._(
            provider,
            root,
            symlinkPrefix,
            null /* readonly */,
            binPaths,
            context.join(root, '$symlinkPrefix-genfiles'),
            lookForBuildFileSubstitutes: lookForBuildFileSubstitutes);
      }
    }

    return null;
  }

  /// Find the "bin" folder path, by searching for it.
  ///
  /// Depending on the environment we're working in (source code tree, build
  /// environment subtree of sources, local workspace, blaze, bazel), the "bin"
  /// folder may be available at a symlink found at `$root/blaze-bin/` or
  /// `$root/bazel-bin/`. If that symlink is not available, then we must search
  /// the immediate folders found in `$root/blaze-out/` and `$root/bazel-out/`
  /// for folders named "bin".
  ///
  /// If no "bin" folder is found in any of those locations, empty list is
  /// returned.
  static List<String> _findBinFolderPaths(Folder root) {
    var out = _firstExistingFolder(root, ['blaze-out', 'bazel-out']);
    if (out == null) {
      return [];
    }

    List<String> binPaths = [];
    for (var child in out.getChildren().whereType<Folder>()) {
      // Children are folders denoting architectures and build flags, like
      // 'k8-opt', 'k8-fastbuild', perhaps 'host'.
      Folder possibleBin = child.getChildAssumingFolder('bin');
      if (possibleBin.exists) {
        binPaths.add(possibleBin.path);
      }
    }
    return binPaths;
  }

  /// Return the symlink prefix, _X_, for folders `X-bin` or `X-genfiles`.
  ///
  /// If the workspace's "bin" folders were already found, the symlink prefix is
  /// determined from one of the [binPaths]. Otherwise it is determined by
  /// probing the internal `blaze-genfiles` and `bazel-genfiles`. Make a default
  /// assumption according to [defaultSymlinkPrefix] if neither of the folders
  /// exists.
  static String _findSymlinkPrefix(ResourceProvider provider, String root,
      {List<String>? binPaths}) {
    path.Context context = provider.pathContext;
    if (binPaths != null && binPaths.isNotEmpty) {
      return context.basename(binPaths.first).startsWith('bazel')
          ? 'bazel'
          : 'blaze';
    }
    if (provider.getFolder(context.join(root, 'blaze-genfiles')).exists) {
      return 'blaze';
    }
    if (provider.getFolder(context.join(root, 'bazel-genfiles')).exists) {
      return 'bazel';
    }
    // Couldn't find it.  Make a default assumption.
    return defaultSymlinkPrefix;
  }

  /// Return the first folder within [root], chosen from [names], which exists.
  static Folder? _firstExistingFolder(Folder root, List<String> names) => names
      .map((name) => root.getChildAssumingFolder(name))
      .firstWhereOrNull((folder) => folder.exists);

  /// Return the default language version of the workspace.
  ///
  /// Return `null` if cannot be read, for example because the file does not
  /// exist, or is not available in this build configuration (batch analysis).
  static Version? _readLanguageVersion(
    ResourceProvider resourceProvider,
    String rootPath,
  ) {
    var file = resourceProvider.getFile(
      resourceProvider.pathContext.joinAll(
        [rootPath, 'dart', 'build_defs', 'bzl', 'language.bzl'],
      ),
    );

    String content;
    try {
      content = file.readAsStringSync();
    } on FileSystemException {
      return null;
    }

    final pattern = RegExp(r'_version_null_safety\s*=\s*"(\d+\.\d+)"');
    for (var match in pattern.allMatches(content)) {
      return Version.parse('${match.group(1)}.0');
    }

    return null;
  }
}

/// Information about a package defined in a BazelWorkspace.
///
/// Separate from [Packages] or package maps, this class is designed to simply
/// understand whether arbitrary file paths represent libraries declared within
/// a given package in a BazelWorkspace.
class BazelWorkspacePackage extends WorkspacePackage {
  /// A prefix for any URI of a path in this package.
  final String _uriPrefix;

  @override
  final String root;

  @override
  final BazelWorkspace workspace;

  bool _buildFileReady = false;
  List<String>? _enabledExperiments;
  Version? _languageVersion;

  BazelWorkspacePackage(String packageName, this.root, this.workspace)
      : _uriPrefix = 'package:$packageName/';

  @override
  List<String>? get enabledExperiments {
    _readBuildFile();
    return _enabledExperiments;
  }

  @override
  Version? get languageVersion {
    _readBuildFile();
    return _languageVersion ?? workspace._languageVersion;
  }

  @override
  bool contains(Source source) {
    var uri = source.uri;
    if (uri.isScheme('package')) {
      return uri.toString().startsWith(_uriPrefix);
    }

    var path = source.fullName;
    return workspace.findPackageFor(path)?.root == root;
  }

  @override
  // TODO(brianwilkerson) Implement this by looking in the BUILD file for 'deps'
  //  lists.
  Map<String, List<Folder>> packagesAvailableTo(String libraryPath) =>
      <String, List<Folder>>{};

  @override
  bool sourceIsInPublicApi(Source source) {
    var filePath = filePathFromSource(source);
    if (filePath == null) return false;

    var libFolder = workspace.provider.pathContext.join(root, 'lib');
    if (workspace.provider.pathContext.isWithin(libFolder, filePath)) {
      // A file in "$root/lib" is public iff it is not in "$root/lib/src".
      var libSrcFolder = workspace.provider.pathContext.join(libFolder, 'src');
      return !workspace.provider.pathContext.isWithin(libSrcFolder, filePath);
    }

    var relativeRoot =
        workspace.provider.pathContext.relative(root, from: workspace.root);
    for (var binPath in workspace.binPaths) {
      libFolder =
          workspace.provider.pathContext.join(binPath, relativeRoot, 'lib');
      if (workspace.provider.pathContext.isWithin(libFolder, filePath)) {
        // A file in "$bin/lib" is public iff it is not in "$bin/lib/src".
        var libSrcFolder =
            workspace.provider.pathContext.join(libFolder, 'src');
        return !workspace.provider.pathContext.isWithin(libSrcFolder, filePath);
      }
    }

    libFolder = workspace.provider.pathContext
        .join(workspace.genfiles, relativeRoot, 'lib');
    if (workspace.provider.pathContext.isWithin(libFolder, filePath)) {
      // A file in "$genfiles/lib" is public iff it is not in
      // "$genfiles/lib/src".
      var libSrcFolder = workspace.provider.pathContext.join(libFolder, 'src');
      return !workspace.provider.pathContext.isWithin(libSrcFolder, filePath);
    }

    return false;
  }

  void _readBuildFile() {
    if (_buildFileReady) {
      return;
    }

    try {
      _buildFileReady = true;
      var buildContent = workspace.provider
          .getFolder(root)
          .getChildAssumingFile('BUILD')
          .readAsStringSync();
      var flattenedBuildContent = buildContent
          .split('\n')
          .map((e) => e.trim())
          .where((e) => !e.startsWith('#'))
          .map((e) => e.replaceAll(' ', ''))
          .join();
      var hasNonNullableFlag = const {
        'dart_package(null_safety=True',
        'dart_package(sound_null_safety=True',
      }.any(flattenedBuildContent.contains);
      if (hasNonNullableFlag) {
        // Enabled by default.
      } else {
        _languageVersion = Version.parse('2.9.0');
      }
    } on FileSystemException {
      // ignored
    }
  }
}
