// 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/analysis_context.dart';
import 'package:analyzer/dart/analysis/context_builder.dart';
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/context/builder.dart' as old
    show ContextBuilder, ContextBuilderOptions;
import 'package:analyzer/src/context/context_root.dart' as old;
import 'package:analyzer/src/dart/analysis/driver.dart'
    show AnalysisDriver, AnalysisDriverScheduler;
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart'
    show FileContentOverlay;
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/sdk.dart' show DartSdkManager;
import 'package:analyzer/src/generated/source.dart' show ContentCache;
import 'package:analyzer/src/dart/analysis/performance_logger.dart'
    show PerformanceLog;
import 'package:front_end/src/byte_store/byte_store.dart'
    show ByteStore, MemoryByteStore;
import 'package:meta/meta.dart';

/**
 * An implementation of a context builder.
 */
class ContextBuilderImpl implements ContextBuilder {
  /**
   * The resource provider used to access the file system.
   */
  final ResourceProvider resourceProvider;

  /**
   * 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 the path to the default location of the SDK, or `null` if the sdk
   * cannot be found.
   */
  String get _defaultSdkPath =>
      FolderBasedDartSdk.defaultSdkDirectory(resourceProvider)?.path;

  @override
  AnalysisContext createContext(
      {@deprecated ByteStore byteStore,
      @required ContextRoot contextRoot,
      DeclaredVariables declaredVariables,
      @deprecated PerformanceLog performanceLog,
      @deprecated AnalysisDriverScheduler scheduler,
      String sdkPath}) {
    byteStore ??= new MemoryByteStore();
    performanceLog ??= new PerformanceLog(new StringBuffer());

    sdkPath ??= _defaultSdkPath;
    if (sdkPath == null) {
      throw new ArgumentError('Cannot find path to the SDK');
    }
    DartSdkManager sdkManager = new DartSdkManager(sdkPath, true);

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

    // TODO(brianwilkerson) Move the required implementation from the old
    // ContextBuilder to this class and remove the old class.
    old.ContextBuilderOptions options = new old.ContextBuilderOptions();
    if (declaredVariables != null) {
      options.declaredVariables = _toMap(declaredVariables);
    }
    options.defaultPackageFilePath = contextRoot.packagesFile?.path;

    old.ContextBuilder builder = new old.ContextBuilder(
        resourceProvider, sdkManager, new ContentCache(),
        options: options);
    builder.analysisDriverScheduler = scheduler;
    builder.byteStore = byteStore;
    builder.fileContentOverlay = new FileContentOverlay();
    builder.performanceLog = performanceLog;

    old.ContextRoot oldContextRoot = new old.ContextRoot(
        contextRoot.root.path, contextRoot.excludedPaths.toList(),
        pathContext: resourceProvider.pathContext);
    AnalysisDriver driver = builder.buildDriver(oldContextRoot);

    // AnalysisDriver reports results into streams.
    // We need to drain these streams to avoid memory leak.
    driver.results.drain();
    driver.exceptions.drain();

    DriverBasedAnalysisContext context =
        new DriverBasedAnalysisContext(resourceProvider, contextRoot, driver);
    return context;
  }

  /**
   * Convert the [declaredVariables] into a map for use with the old context
   * builder.
   */
  Map<String, String> _toMap(DeclaredVariables declaredVariables) {
    Map<String, String> map = <String, String>{};
    for (String name in declaredVariables.variableNames) {
      map[name] = declaredVariables.get(name);
    }
    return map;
  }
}
