// 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 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/task/model.dart';
import 'package:analyzer/task/model.dart';
import 'package:package_config/packages.dart';
import 'package:yaml/src/yaml_node.dart';
import 'package:yaml/yaml.dart';

/// The descriptor used to associate analysis configuration with analysis
/// contexts in configuration data.
final ResultDescriptor<AnalysisConfiguration> ANALYSIS_CONFIGURATION =
    new ResultDescriptorImpl('analysis.config', null);

/// Return configuration associated with this [context], or `null` if there is
/// none.
AnalysisConfiguration getConfiguration(AnalysisContext context) =>
    context.getConfigurationData(ANALYSIS_CONFIGURATION)
    as AnalysisConfiguration;

/// Associate this [config] with the given [context].
void setConfiguration(AnalysisContext context, AnalysisConfiguration config) {
  context.setConfigurationData(ANALYSIS_CONFIGURATION, config);
}

/// Analysis configuration.
abstract class AnalysisConfiguration {
  final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
  final Packages packages;
  final ResourceProvider resourceProvider;
  AnalysisConfiguration(this.resourceProvider, this.packages);

  factory AnalysisConfiguration.fromPubspec(
          File pubspec, ResourceProvider resourceProvider, Packages packages) =>
      new PubspecConfiguration(pubspec, resourceProvider, packages);

  /// Get a map of options defined by this configuration (or `null` if none
  /// are specified).
  Map get options;
}

/// Describes an analysis configuration.
class AnalysisConfigurationDescriptor {
  /// The name of the package hosting the configuration.
  String package;
  /// The name of the configuration "pragma".
  String pragma;

  AnalysisConfigurationDescriptor.fromAnalyzerOptions(Map analyzerOptions) {
    Object config = analyzerOptions['configuration'];
    if (config is String) {
      List<String> items = config.split('/');
      if (items.length == 2) {
        package = items[0].trim();
        pragma = items[1].trim();
      }
    }
  }

  /// Return true if this descriptor is valid.
  bool get isValid => package != null && pragma != null;
}

/// Pubspec-specified analysis configuration.
class PubspecConfiguration extends AnalysisConfiguration {
  final File pubspec;
  PubspecConfiguration(
      this.pubspec, ResourceProvider resourceProvider, Packages packages)
      : super(resourceProvider, packages);

  @override
  Map get options {
    //Safest not to cache (requested infrequently).
    if (pubspec.exists) {
      try {
        String contents = pubspec.readAsStringSync();
        YamlNode map = loadYamlNode(contents);
        if (map is YamlMap) {
          YamlNode config = map['analyzer'];
          if (config is YamlMap) {
            AnalysisConfigurationDescriptor descriptor =
                new AnalysisConfigurationDescriptor.fromAnalyzerOptions(config);

            if (descriptor.isValid) {
              //Create a path, given descriptor and packagemap
              Uri uri = packages.asMap()[descriptor.package];
              Uri pragma = new Uri.file('config/${descriptor.pragma}.yaml',
                  windows: false);
              Uri optionsUri = uri.resolveUri(pragma);
              File file = resourceProvider.getFile(optionsUri.toFilePath());
              if (file.exists) {
                return optionsProvider.getOptionsFromFile(file);
              }
            }
          }
        }
      } catch (_) {
        // Skip exceptional configurations.
      }
    }
    return null;
  }
}
