// Copyright (c) 2019, 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 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/lint/pub.dart';
import 'package:analyzer/src/workspace/simple.dart';
import 'package:analyzer/src/workspace/workspace.dart';

/// Information about a Pub workspace.
class PubWorkspace extends SimpleWorkspace {
  /// The name of the file that identifies the root of the workspace.
  static const String _pubspecName = 'pubspec.yaml';

  /// The singular package in this workspace.
  ///
  /// Each Pub workspace is itself one package.
  late final PubWorkspacePackage _theOnlyPackage;

  /// The associated pubspec file.
  final File _pubspecFile;

  PubWorkspace._(
    ResourceProvider provider,
    Map<String, List<Folder>> packageMap,
    String root,
    this._pubspecFile,
  ) : super(provider, packageMap, root) {
    _theOnlyPackage = PubWorkspacePackage(root, this);
  }

  @override
  WorkspacePackage? findPackageFor(String filePath) {
    final Folder folder = provider.getFolder(filePath);
    if (provider.pathContext.isWithin(root, folder.path)) {
      return _theOnlyPackage;
    } else {
      return null;
    }
  }

  /// Find the pub workspace that contains the given [filePath].
  static PubWorkspace? find(
    ResourceProvider provider,
    Map<String, List<Folder>> packageMap,
    String filePath,
  ) {
    var start = provider.getFolder(filePath);
    for (var current in start.withAncestors) {
      var pubspec = current.getChildAssumingFile(_pubspecName);
      if (pubspec.exists) {
        var root = current.path;
        return PubWorkspace._(provider, packageMap, root, pubspec);
      }
    }
  }
}

/// Information about a package defined in a [PubWorkspace].
///
/// 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 [PubWorkspace].
class PubWorkspacePackage extends WorkspacePackage {
  @override
  final String root;

  Pubspec? _pubspec;

  /// A flag to indicate if we've tried to parse the pubspec.
  bool _parsedPubspec = false;

  @override
  final PubWorkspace workspace;

  PubWorkspacePackage(this.root, this.workspace);

  /// Get the associated parsed [Pubspec], or `null` if there was an error in
  /// reading or parsing.
  Pubspec? get pubspec {
    if (!_parsedPubspec) {
      _parsedPubspec = true;
      try {
        final content = workspace._pubspecFile.readAsStringSync();
        _pubspec = Pubspec.parse(content);
      } catch (_) {
        // Pubspec will be null.
      }
    }
    return _pubspec;
  }

  @override
  bool contains(Source source) {
    var filePath = filePathFromSource(source);
    if (filePath == null) return false;
    // There is a 1-1 relationship between [PubWorkspace]s and
    // [PubWorkspacePackage]s. If a file is in a package's workspace, then it
    // is in the package as well.
    return workspace.provider.pathContext.isWithin(root, filePath);
  }

  @override
  Map<String, List<Folder>> packagesAvailableTo(String libraryPath) {
    // TODO(brianwilkerson) Consider differentiating based on whether the
    //  [libraryPath] is inside the `lib` directory.
    return workspace.packageMap;
  }

  @override

  /// A Pub package's public API consists of libraries found in the top-level
  /// "lib" directory, and any subdirectories, excluding the "src" directory
  /// just inside the top-level "lib" directory.
  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)) {
      return false;
    }
    var libSrcFolder = workspace.provider.pathContext.join(root, 'lib', 'src');
    return !workspace.provider.pathContext.isWithin(libSrcFolder, filePath);
  }
}
