// 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.

library analyzer.src.plugin.plugin_configuration;

import 'package:analyzer/plugin/options.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:yaml/yaml.dart';

const _analyzerOptionScope = 'analyzer';

const _pluginOptionScope = 'plugins';

/// Parse the given string into a plugin manifest.
PluginManifest parsePluginManifestString(String manifestSource) {
  var yaml = loadYaml(manifestSource);
  if (yaml == null) {
    return null;
  }
  _verifyMap(yaml, 'plugin manifest');
  Iterable<String> pluginHost = _parseHosts(yaml['contributes_to']);
  PluginInfo plugin = _parsePlugin(yaml);
  return new PluginManifest(contributesTo: pluginHost, plugin: plugin);
}

String _asString(dynamic yaml) {
  if (yaml != null && yaml is! String) {
    throw new PluginConfigFormatException(
        'Unable to parse pugin manifest, '
        'expected `String`, got `${yaml.runtimeType}`',
        yaml);
  }
  return yaml;
}

Iterable<String> _parseHosts(dynamic yaml) {
  List<String> hosts = <String>[];
  if (yaml is String) {
    hosts.add(yaml);
  } else if (yaml is YamlList) {
    yaml.forEach((h) => hosts.add(_asString(h)));
  }
  return hosts;
}

PluginInfo _parsePlugin(dynamic yaml) {
  if (yaml != null) {
    _verifyMap(yaml, 'plugin manifest');
    return new PluginInfo._fromYaml(details: yaml);
  }
  return null;
}

PluginInfo _processPluginMapping(dynamic name, dynamic details) {
  if (name is String) {
    if (details is String) {
      return new PluginInfo(name: name, version: details);
    }
    if (details is YamlMap) {
      return new PluginInfo._fromYaml(name: name, details: details);
    }
  }

  return null;
}

_verifyMap(dynamic yaml, String context) {
  if (yaml is! YamlMap) {
    throw new PluginConfigFormatException(
        'Unable to parse $context, '
        'expected `YamlMap`, got `${yaml.runtimeType}`',
        yaml);
  }
}

/// A callback for error handling.
typedef ErrorHandler(Exception e);

/// Describes plugin configuration information as extracted from an
/// analysis options map or plugin manifest.
class PluginConfig {
  final Iterable<PluginInfo> plugins;
  PluginConfig(this.plugins);

  /// Create a plugin configuration from an options map.
  factory PluginConfig.fromOptions(Map<String, YamlNode> options) {
    List<PluginInfo> plugins = [];
    var analyzerOptions = options[_analyzerOptionScope];
    if (analyzerOptions != null) {
      if (analyzerOptions is YamlMap) {
        var pluginConfig = analyzerOptions[_pluginOptionScope];
        if (pluginConfig is YamlMap) {
          pluginConfig.forEach((name, details) {
            var plugin = _processPluginMapping(name, details);
            if (plugin != null) {
              plugins.add(plugin);
            }
          });
        } else {
          // Anything but an empty list of plugins is treated as a format error.
          if (pluginConfig != null) {
            throw new PluginConfigFormatException(
                'Unrecognized plugin config format, expected `YamlMap`, '
                'got `${pluginConfig.runtimeType}`',
                pluginConfig);
          }
        }
      }
    }

    return new PluginConfig(plugins);
  }
}

/// Thrown on bad plugin config format.
class PluginConfigFormatException implements Exception {
  /// Descriptive message.
  final message;

  /// The `plugin:` yaml node for generating detailed error feedback.
  final yamlNode;
  PluginConfigFormatException(this.message, this.yamlNode);
}

/// Extracts plugin config details from analysis options.
class PluginConfigOptionsProcessor extends OptionsProcessor {
  final ErrorHandler _errorHandler;

  PluginConfig _config;

  PluginConfigOptionsProcessor([this._errorHandler]);

  /// The processed plugin config.
  PluginConfig get config => _config;

  @override
  void onError(Exception exception) {
    if (_errorHandler != null) {
      _errorHandler(exception);
    }
  }

  @override
  void optionsProcessed(
      AnalysisContext context, Map<String, YamlNode> options) {
    _config = new PluginConfig.fromOptions(options);
  }
}

/// Describes plugin information.
class PluginInfo {
  final String name;
  final String className;
  final String version;
  final String libraryUri;
  final String packageName;
  final String path;
  PluginInfo(
      {this.name,
      this.version,
      this.className,
      this.libraryUri,
      this.packageName,
      this.path});

  factory PluginInfo._fromYaml({String name, YamlMap details}) =>
      new PluginInfo(
          name: name,
          version: _asString(details['version']),
          className: _asString(details['class_name']),
          libraryUri: _asString(details['library_uri']),
          packageName: _asString(details['package_name']),
          path: _asString(details['path']));
}

/// Plugin manifests accompany plugin packages, providing
/// configuration information for published plugins.
///
/// Provisionally, plugin manifests live in a file `plugin.yaml`
/// at the root of the plugin package.
///
///     my_plugin/
///       bin/
///       lib/
///       plugin.yaml
///       pubspec.yaml
///
/// Provisional manifest file format:
///
///     class_name: MyAnalyzerPlugin
///     library_uri: 'my_plugin/my_analyzer_plugin.dart'
///     contributes_to: analyzer
class PluginManifest {
  PluginInfo plugin;
  Iterable<String> contributesTo;
  PluginManifest({this.plugin, this.contributesTo});
}
