// Copyright (c) 2015, 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'
    show ResourceProvider, ResourceUriResolver;
import 'package:analyzer/file_system/physical_file_system.dart'
    show PhysicalResourceProvider;
import 'package:analyzer/source/custom_resolver.dart';
import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/command_line/arguments.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/generated/source.dart'
    show DartUriResolver, SourceFactory, UriResolver;
import 'package:analyzer/src/summary/package_bundle_reader.dart'
    show InSummaryUriResolver, SummaryDataStore;
import 'package:args/args.dart' show ArgParser, ArgResults;
import 'package:cli_util/cli_util.dart' show getSdkDir;
import 'package:path/path.dart' as path;

// ignore_for_file: deprecated_member_use

/// Options used to set up Source URI resolution in the analysis context.
class AnalyzerOptions {
  final ContextBuilderOptions contextBuilderOptions;

  /// Custom URI mappings, such as "dart:foo" -> "path/to/foo.dart"
  final Map<String, String> customUrlMappings;

  /// Package root when resolving 'package:' urls the standard way.
  String get packageRoot => contextBuilderOptions.defaultPackagesDirectoryPath;

  /// List of summary file paths.
  final List<String> summaryPaths;

  final Map<String, String> customSummaryModules = {};

  /// Path to the dart-sdk, or `null` if the path couldn't be determined.
  final String dartSdkPath;

  /// Path to the dart-sdk summary.  If this is set, it will be used in favor
  /// of the unsummarized one.
  String get dartSdkSummaryPath => contextBuilderOptions.dartSdkSummaryPath;

  /// Defined variables used by `bool.fromEnvironment` etc.
  Map<String, String> get declaredVariables =>
      contextBuilderOptions.declaredVariables;

  AnalyzerOptions._(
      {this.contextBuilderOptions,
      List<String> summaryPaths,
      String dartSdkPath,
      this.customUrlMappings: const {}})
      : dartSdkPath = dartSdkPath ?? getSdkDir().path,
        summaryPaths = summaryPaths ?? const [] {
    contextBuilderOptions.declaredVariables ??= const {};
    _parseCustomSummaryModules();
  }

  factory AnalyzerOptions.basic(
      {String dartSdkPath,
      String dartSdkSummaryPath,
      List<String> summaryPaths}) {
    var contextBuilderOptions = new ContextBuilderOptions()
      ..defaultOptions = (new AnalysisOptionsImpl()
        ..strongMode = true
        ..previewDart2 = true)
      ..dartSdkSummaryPath = dartSdkSummaryPath;

    return new AnalyzerOptions._(
        contextBuilderOptions: contextBuilderOptions,
        dartSdkPath: dartSdkPath,
        summaryPaths: summaryPaths);
  }

  factory AnalyzerOptions.fromArguments(ArgResults args,
      {String dartSdkSummaryPath, List<String> summaryPaths}) {
    var contextBuilderOptions = createContextBuilderOptions(args,
        strongMode: true, trackCacheDependencies: false);
    (contextBuilderOptions.defaultOptions as AnalysisOptionsImpl).previewDart2 =
        true;

    var dartSdkPath = args['dart-sdk'] ?? getSdkDir().path;

    dartSdkSummaryPath ??= contextBuilderOptions.dartSdkSummaryPath;
    dartSdkSummaryPath ??=
        path.join(dartSdkPath, 'lib', '_internal', 'ddc_sdk.sum');
    // For building the SDK, we explicitly set the path to none.
    if (dartSdkSummaryPath == 'build') dartSdkSummaryPath = null;
    contextBuilderOptions.dartSdkSummaryPath = dartSdkSummaryPath;

    return new AnalyzerOptions._(
        contextBuilderOptions: contextBuilderOptions,
        summaryPaths: summaryPaths ?? args['summary'] as List<String>,
        dartSdkPath: dartSdkPath,
        customUrlMappings: _parseUrlMappings(args['url-mapping']));
  }

  static void addArguments(ArgParser parser, {bool hide: true}) {
    parser
      ..addOption('summary',
          abbr: 's', help: 'summary file(s) to include', allowMultiple: true)
      ..addOption('url-mapping',
          help: '--url-mapping=libraryUri,/path/to/library.dart uses\n'
              'library.dart as the source for an import of of "libraryUri".',
          allowMultiple: true,
          splitCommas: false);
  }

  static Map<String, String> _parseUrlMappings(Iterable argument) {
    var mappings = <String, String>{};
    for (var mapping in argument) {
      var splitMapping = mapping.split(',');
      if (splitMapping.length >= 2) {
        mappings[splitMapping[0]] = path.absolute(splitMapping[1]);
      }
    }
    return mappings;
  }

  /// A summary path can contain "=" followed by an explicit module name to
  /// allow working with summaries whose physical location is outside of the
  /// module root directory.
  ///
  /// Removes any explicit module names from [summaryPaths] and populates with
  /// [customSummaryModules] with them.
  void _parseCustomSummaryModules() {
    for (var i = 0; i < summaryPaths.length; i++) {
      var summaryPath = summaryPaths[i];
      var pipe = summaryPath.indexOf("=");
      if (pipe != -1) {
        summaryPaths[i] = summaryPath.substring(0, pipe);
        customSummaryModules[summaryPaths[i]] = summaryPath.substring(pipe + 1);
      }
    }
  }
}

/// Creates a SourceFactory configured by the [options].
///
/// If supplied, [fileResolvers] will override the default `file:` and
/// `package:` URI resolvers.
SourceFactory createSourceFactory(AnalyzerOptions options,
    {DartUriResolver sdkResolver,
    List<UriResolver> fileResolvers,
    SummaryDataStore summaryData,
    ResourceProvider resourceProvider}) {
  resourceProvider ??= PhysicalResourceProvider.INSTANCE;
  var resolvers = <UriResolver>[];
  if (options.customUrlMappings.isNotEmpty) {
    resolvers.add(
        new CustomUriResolver(resourceProvider, options.customUrlMappings));
  }
  resolvers.add(sdkResolver);
  if (summaryData != null) {
    resolvers.add(new InSummaryUriResolver(resourceProvider, summaryData));
  }

  if (fileResolvers == null)
    fileResolvers =
        createFileResolvers(options, resourceProvider: resourceProvider);
  resolvers.addAll(fileResolvers);
  return new SourceFactory(resolvers, null, resourceProvider);
}

List<UriResolver> createFileResolvers(AnalyzerOptions options,
    {ResourceProvider resourceProvider}) {
  resourceProvider ??= PhysicalResourceProvider.INSTANCE;
  UriResolver packageResolver() {
    var builderOptions = new ContextBuilderOptions();
    if (options.packageRoot != null) {
      builderOptions.defaultPackagesDirectoryPath = options.packageRoot;
    }
    var builder = new ContextBuilder(resourceProvider, null, null,
        options: builderOptions);

    return new PackageMapUriResolver(resourceProvider,
        builder.convertPackagesToMap(builder.createPackageMap('')));
  }

  return [new ResourceUriResolver(resourceProvider), packageResolver()];
}
