// Copyright (c) 2018, 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/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/dart/analysis/analysis_options.dart';
import 'package:analyzer/src/dart/analysis/analysis_options_map.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart'
    show ByteStore, MemoryByteStore;
import 'package:analyzer/src/dart/analysis/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart'
    show
        AnalysisDriver,
        AnalysisDriverScheduler,
        AnalysisDriverTestView,
        OwnedFiles;
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/dart/analysis/file_content_cache.dart';
import 'package:analyzer/src/dart/analysis/info_declaration_store.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart'
    show PerformanceLog;
import 'package:analyzer/src/dart/analysis/unlinked_unit_store.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/summary/summary_sdk.dart';
import 'package:analyzer/src/summary2/macro.dart';
import 'package:analyzer/src/summary2/package_bundle_format.dart';
import 'package:analyzer/src/util/sdk.dart';
import 'package:analyzer/src/workspace/workspace.dart';

/// A utility class used to build an analysis context based on a context root.
class ContextBuilderImpl {
  /// The resource provider used to access the file system.
  final ResourceProvider resourceProvider;

  /// Analysis options mappings shared by all contexts built by this builder.
  final AnalysisOptionsMap _optionsMap = AnalysisOptionsMap();

  /// Initialize a newly created context builder. If a [resourceProvider] is
  /// given, then it will be used to access the file system, otherwise the
  /// default resource provider will be used.
  ContextBuilderImpl({ResourceProvider? resourceProvider})
      : resourceProvider =
            resourceProvider ?? PhysicalResourceProvider.INSTANCE;

  /// Return an analysis context corresponding to the given [contextRoot].
  ///
  /// If a set of [declaredVariables] is provided, the values will be used to
  /// map the variable names found in `fromEnvironment` invocations to the
  /// constant value that will be returned. If none is given, then no variables
  /// will be defined.
  ///
  /// If a list of [librarySummaryPaths] is provided, then the summary files at
  /// those paths will be used, when possible, when analyzing the libraries
  /// contained in the summary files.
  ///
  /// If an [sdkPath] is provided, and if it is a valid path to a directory
  /// containing a valid SDK, then the SDK in the referenced directory will be
  /// used when analyzing the code in the context.
  ///
  /// If an [sdkSummaryPath] is provided, then that file will be used as the
  /// summary file for the SDK.
  DriverBasedAnalysisContext createContext({
    ByteStore? byteStore,
    required ContextRoot contextRoot,
    bool definedOptionsFile = false,
    DeclaredVariables? declaredVariables,
    bool drainStreams = true,
    bool enableIndex = false,
    List<String>? librarySummaryPaths,
    PerformanceLog? performanceLog,
    bool retainDataForTesting = false,
    AnalysisDriverScheduler? scheduler,
    String? sdkPath,
    String? sdkSummaryPath,
    void Function({
      required AnalysisOptionsImpl analysisOptions,
      required ContextRoot contextRoot,
      required DartSdk sdk,
    })? updateAnalysisOptions2,
    FileContentCache? fileContentCache,
    UnlinkedUnitStore? unlinkedUnitStore,
    InfoDeclarationStore? infoDeclarationStore,
    MacroSupport? macroSupport,
    OwnedFiles? ownedFiles,
  }) {
    // TODO(scheglov): Remove this, and make `sdkPath` required.
    sdkPath ??= getSdkPath();
    ArgumentError.checkNotNull(sdkPath, 'sdkPath');

    byteStore ??= MemoryByteStore();
    performanceLog ??= PerformanceLog(null);

    if (scheduler == null) {
      scheduler = AnalysisDriverScheduler(performanceLog);
      scheduler.start();
    }

    SummaryDataStore? summaryData;
    if (librarySummaryPaths != null) {
      summaryData = SummaryDataStore();
      for (var summaryPath in librarySummaryPaths) {
        var bytes = resourceProvider.getFile(summaryPath).readAsBytesSync();
        var bundle = PackageBundleReader(bytes);
        summaryData.addBundle(summaryPath, bundle);
      }
    }

    var workspace = contextRoot.workspace;
    var sdk = _createSdk(
      workspace: workspace,
      sdkPath: sdkPath,
      sdkSummaryPath: sdkSummaryPath,
    );

    // TODO(scheglov): Ensure that "librarySummaryPaths" not null only
    // when "sdkSummaryPath" is not null.
    if (sdk is SummaryBasedDartSdk) {
      summaryData?.addBundle(null, sdk.bundle);
    }

    var optionsFile = contextRoot.optionsFile;
    var sourceFactory = workspace.createSourceFactory(sdk, summaryData);

    AnalysisOptionsMap analysisOptionsMap;
    // If there's an options file defined (as, e.g. passed into the
    // AnalysisContextCollection), use a shared options map based on it.
    if (definedOptionsFile && optionsFile != null) {
      analysisOptionsMap = AnalysisOptionsMap.forSharedOptions(
          _getAnalysisOptions(contextRoot, optionsFile, sourceFactory, sdk,
              updateAnalysisOptions2));
    } else {
      // Otherwise, create one from the options file mappings stored in the
      // context root.
      analysisOptionsMap = _createOptionsMap(
          contextRoot, sourceFactory, updateAnalysisOptions2, sdk);
    }

    var analysisContext =
        DriverBasedAnalysisContext(resourceProvider, contextRoot);
    var driver = AnalysisDriver(
      scheduler: scheduler,
      logger: performanceLog,
      resourceProvider: resourceProvider,
      byteStore: byteStore,
      sourceFactory: sourceFactory,
      analysisOptionsMap: analysisOptionsMap,
      packages: _createPackageMap(
        contextRoot: contextRoot,
      ),
      analysisContext: analysisContext,
      enableIndex: enableIndex,
      externalSummaries: summaryData,
      retainDataForTesting: retainDataForTesting,
      fileContentCache: fileContentCache,
      unlinkedUnitStore: unlinkedUnitStore,
      infoDeclarationStore: infoDeclarationStore,
      macroSupport: macroSupport,
      declaredVariables: declaredVariables,
      testView: retainDataForTesting ? AnalysisDriverTestView() : null,
      ownedFiles: ownedFiles,
    );

    // AnalysisDriver reports results into streams.
    // We need to drain these streams to avoid memory leak.
    if (drainStreams) {
      driver.exceptions.drain<void>();
    }

    return analysisContext;
  }

  /// Create an [AnalysisOptionsMap] for the given [contextRoot].
  AnalysisOptionsMap _createOptionsMap(
      ContextRoot contextRoot,
      SourceFactory sourceFactory,
      void Function(
              {required AnalysisOptionsImpl analysisOptions,
              required ContextRoot contextRoot,
              required DartSdk sdk})?
          updateAnalysisOptions,
      DartSdk sdk) {
    var provider = AnalysisOptionsProvider(sourceFactory);

    void updateOptions(AnalysisOptionsImpl options) {
      if (updateAnalysisOptions != null) {
        updateAnalysisOptions(
          analysisOptions: options,
          contextRoot: contextRoot,
          sdk: sdk,
        );
      }
    }

    var optionsMappings =
        (contextRoot as ContextRootImpl).optionsFileMap.entries;
    for (var entry in optionsMappings) {
      var file = entry.value;
      var options = AnalysisOptionsImpl.fromYaml(
          file: file, optionsMap: provider.getOptionsFromFile(file));

      _optionsMap.add(entry.key, options);
    }

    _optionsMap.forEachOptionsObject(updateOptions);
    return _optionsMap;
  }

  /// Return [Packages] to analyze the [contextRoot].
  ///
  // TODO(scheglov): Get [Packages] from [Workspace]?
  Packages _createPackageMap({
    required ContextRoot contextRoot,
  }) {
    var packagesFile = contextRoot.packagesFile;
    if (packagesFile != null) {
      return parsePackageConfigJsonFile(resourceProvider, packagesFile);
    } else {
      return Packages.empty;
    }
  }

  /// Return the SDK that should be used to analyze code.
  DartSdk _createSdk({
    required Workspace workspace,
    String? sdkPath,
    String? sdkSummaryPath,
  }) {
    if (sdkSummaryPath != null) {
      var file = resourceProvider.getFile(sdkSummaryPath);
      var bytes = file.readAsBytesSync();
      return SummaryBasedDartSdk.forBundle(
        PackageBundleReader(bytes),
      );
    }

    var folderSdk = FolderBasedDartSdk(
      resourceProvider,
      resourceProvider.getFolder(sdkPath!),
    );

    {
      // TODO(scheglov): We already had partial SourceFactory in ContextLocatorImpl.
      var partialSourceFactory = workspace.createSourceFactory(null, null);
      var embedderYamlSource = partialSourceFactory.forUri(
        'package:sky_engine/_embedder.yaml',
      );
      if (embedderYamlSource != null) {
        var embedderYamlPath = embedderYamlSource.fullName;
        var libFolder = resourceProvider.getFile(embedderYamlPath).parent;
        var locator = EmbedderYamlLocator.forLibFolder(libFolder);
        var embedderMap = locator.embedderYamls;
        if (embedderMap.isNotEmpty) {
          return EmbedderSdk(
            resourceProvider,
            embedderMap,
            languageVersion: folderSdk.languageVersion,
          );
        }
      }
    }

    return folderSdk;
  }

  /// Return the analysis options that should be used to analyze code in the
  /// [contextRoot].
  ///
  // TODO(scheglov): We have already loaded it once in [ContextLocatorImpl].
  AnalysisOptionsImpl _getAnalysisOptions(
    ContextRoot contextRoot,
    File? optionsFile,
    SourceFactory sourceFactory,
    DartSdk sdk,
    void Function(
            {required AnalysisOptionsImpl analysisOptions,
            required ContextRoot contextRoot,
            required DartSdk sdk})?
        updateAnalysisOptions,
  ) {
    AnalysisOptionsImpl? options;

    if (optionsFile != null) {
      try {
        var provider = AnalysisOptionsProvider(sourceFactory);
        options = AnalysisOptionsImpl.fromYaml(
          optionsMap: provider.getOptionsFromFile(optionsFile),
          file: optionsFile,
        );
      } catch (e) {
        // Ignore exception.
      }
    }
    options ??= AnalysisOptionsImpl(file: optionsFile);

    if (updateAnalysisOptions != null) {
      updateAnalysisOptions(
        analysisOptions: options,
        contextRoot: contextRoot,
        sdk: sdk,
      );
    }

    return options;
  }
}
