// 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 initialize.build.initializer_plugin;

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:barback/barback.dart';
import 'package:code_transformers/resolver.dart';
import 'package:initialize/transformer.dart';
import 'package:path/path.dart' as path;

/// A plug which allows an initializer to write out an [InitEntry] given some
/// [InitializerData] from an annotation that was found.
abstract class InitializerPlugin {
  /// Whether or not this plugin should be applied to an [Initializer] given
  /// some [InitializerData]. If [true] is returned then this plugin will take
  /// ownership of this [InitializerData] and no subsequent plugins will have
  /// an opportunity to access it.
  bool shouldApply(InitializerPluginData data);

  /// Returns a [String] or [null]. The [String] should represent dart code
  /// which creates a new [InitEntry] and that entry is added to the static
  /// initializers list. If [null] is returned then no entry is added at all for
  /// this [InitializerData].
  String apply(InitializerPluginData data);
}

/// A class which wraps all the default data passed to an [InitializerPlugin]
/// for each annotation.
class InitializerPluginData {
  final InitializerData initializer;
  final AssetId bootstrapId;
  final Map<LibraryElement, String> libraryPrefixes;
  final TransformLogger logger;
  final Resolver resolver;
  InitializerPluginData(this.initializer, this.bootstrapId,
      this.libraryPrefixes, this.resolver, this.logger);
}

/// The basic [InitializerPlugin]. This generates a new [InitEntry] to be added
/// to the static initializers list, and applies to every item it sees.
class DefaultInitializerPlugin implements InitializerPlugin {
  const DefaultInitializerPlugin();

  /// Applies to everything. Put other plugins before this one to override this
  /// behaviour.
  bool shouldApply(InitializerPluginData data) => true;

  /// Creates a normal [InitEntry] string.
  String apply(InitializerPluginData pluginData) {
    var target = buildTarget(pluginData);
    var meta = buildMeta(pluginData);
    return 'new InitEntry($meta, $target)';
  }

  /// Builds a [String] representing the meta of an [InitEntry] given an
  /// [ElementAnnotation] that was found.
  String buildMeta(InitializerPluginData pluginData) {
    var logger = pluginData.logger;
    var elementAnnotation = pluginData.initializer.annotationElement;
    var elementAnnotationElement = elementAnnotation.element;
    if (elementAnnotationElement is ConstructorElement) {
      return buildConstructorMeta(elementAnnotation, pluginData);
    } else if (elementAnnotationElement is PropertyAccessorElement) {
      return buildPropertyMeta(elementAnnotation, pluginData);
    } else {
      logger.error('Unsupported annotation type. Only constructors and '
          'properties are supported as initializers.');
    }
    return null;
  }

  /// Builds a [String] representing the meta of an [InitEntry] given an
  /// [ElementAnnotation] whose element was a [ConstructorElement].
  String buildConstructorMeta(
      ElementAnnotation elementAnnotation, InitializerPluginData pluginData) {
    var logger = pluginData.logger;
    var node = pluginData.initializer.targetNode;
    var metaPrefix =
        pluginData.libraryPrefixes[elementAnnotation.element.library];

    var annotation = pluginData.initializer.annotationNode;
    if (annotation == null) {
      logger.error(
          'Initializer annotations are only supported on libraries, classes, '
          'and top level methods. Found $node.');
    }
    var clazz = annotation.name;
    var constructor = annotation.constructorName == null
        ? ''
        : '.${annotation.constructorName}';
    var args = buildArgumentList(annotation.arguments, pluginData);
    return 'const $metaPrefix.${clazz}$constructor$args';
  }

  /// Builds a [String] representing the meta of an [InitEntry] given an
  /// [ElementAnnotation] whose element was a [PropertyAccessorElement].
  String buildPropertyMeta(
      ElementAnnotation annotation, InitializerPluginData pluginData) {
    var metaPrefix = pluginData.libraryPrefixes[annotation.element.library];
    return '$metaPrefix.${annotation.element.name}';
  }

  /// Builds a [String] for the target of an [InitEntry] given an [Element] that
  /// was annotated.
  String buildTarget(InitializerPluginData pluginData) {
    var element = pluginData.initializer.targetElement;
    var logger = pluginData.logger;
    if (element is LibraryElement) {
      return buildLibraryTarget(element, pluginData);
    } else if (element is ClassElement) {
      return buildClassTarget(element, pluginData);
    } else if (element is FunctionElement) {
      return buildFunctionTarget(element, pluginData);
    } else {
      logger.error('Initializers can only be applied to top level functions, '
          'libraries, and classes.');
    }
    return null;
  }

  /// Builds a [String] for the target of an [InitEntry] given [element] which
  /// is an annotated class.
  String buildClassTarget(
          ClassElement element, InitializerPluginData pluginData) =>
      buildSimpleTarget(element, pluginData);

  /// Builds a [String] for the target of an [InitEntry] given [element] which
  /// is an annotated function.
  String buildFunctionTarget(
          FunctionElement element, InitializerPluginData pluginData) =>
      buildSimpleTarget(element, pluginData);

  /// Builds a [String] for the target of an [InitEntry] for a simple [Element].
  /// This is just the library prefix followed by the element name.
  String buildSimpleTarget(Element element, InitializerPluginData pluginData) =>
      '${pluginData.libraryPrefixes[element.library]}.${element.name}';

  /// Builds a [String] for the target of an [InitEntry] given [element] which
  /// is an annotated library.
  String buildLibraryTarget(
      LibraryElement element, InitializerPluginData pluginData) {
    var bootstrapId = pluginData.bootstrapId;
    var logger = pluginData.logger;
    var segments = element.source.uri.pathSegments;
    var package = segments[0];
    var libraryPath;
    var packageString;
    if (bootstrapId.package == package &&
        bootstrapId.path.startsWith('${segments[1]}/')) {
      // reset `package` to null, we will do a relative path in this case.
      packageString = 'null';
      libraryPath = path.url.relative(
          path.url.joinAll(segments.getRange(1, segments.length)),
          from: path.url.dirname(path.url.join(bootstrapId.path)));
    } else if (segments[1] == 'lib') {
      packageString = "'$package'";
      libraryPath = path.url.joinAll(segments.getRange(2, segments.length));
    } else {
      logger.error('Unable to import `${element.source.uri.path}` from '
          '${bootstrapId.path}.');
    }

    return "const LibraryIdentifier"
        "(#${element.name}, $packageString, '$libraryPath')";
  }

  /// Builds a [String] representing an [ArgumentList] taking into account the
  /// [libraryPrefixes] from [pluginData].
  String buildArgumentList(
      ArgumentList args, InitializerPluginData pluginData) {
    var buffer = new StringBuffer();
    buffer.write('(');
    var first = true;
    for (var arg in args.arguments) {
      if (!first) buffer.write(', ');
      first = false;

      Expression expression;
      if (arg is NamedExpression) {
        buffer.write('${arg.name.label.name}: ');
        expression = arg.expression;
      } else {
        expression = arg;
      }

      buffer.write(buildExpression(expression, pluginData));
    }
    buffer.write(')');
    return buffer.toString();
  }

  /// Builds a [String] representing [expression] taking into account the
  /// [libraryPrefixes] from [pluginData].
  String buildExpression(
      Expression expression, InitializerPluginData pluginData) {
    var logger = pluginData.logger;
    var libraryPrefixes = pluginData.libraryPrefixes;
    var buffer = new StringBuffer();
    if (expression is StringLiteral && expression.stringValue != null) {
      buffer.write(_stringValue(expression.stringValue));
    } else if (expression is BooleanLiteral ||
        expression is DoubleLiteral ||
        expression is IntegerLiteral ||
        expression is NullLiteral) {
      buffer.write('${expression}');
    } else if (expression is ListLiteral) {
      buffer.write('const [');
      var first = true;
      for (Expression listExpression in expression.elements) {
        if (!first) buffer.write(', ');
        first = false;
        buffer.write(buildExpression(listExpression, pluginData));
      }
      buffer.write(']');
    } else if (expression is MapLiteral) {
      buffer.write('const {');
      var first = true;
      for (MapLiteralEntry entry in expression.entries) {
        if (!first) buffer.write(', ');
        first = false;
        buffer.write(buildExpression(entry.key, pluginData));
        buffer.write(': ');
        buffer.write(buildExpression(entry.value, pluginData));
      }
      buffer.write('}');
    } else if (expression is Identifier) {
      var element = expression.bestElement;
      if (element == null) {
        logger.error('Unable to get `bestElement` for expression: $expression');
      } else if (!element.isPublic) {
        // Inline the evaluated value of private identifiers.
        buffer.write(_evaluateExpression(expression, pluginData));
      } else {
        libraryPrefixes.putIfAbsent(
            element.library, () => 'i${libraryPrefixes.length}');

        buffer.write('${libraryPrefixes[element.library]}.');
        if (element is ClassElement) {
          buffer.write(element.name);
        } else if (element is PropertyAccessorElement) {
          var variable = element.variable;
          if (variable is FieldElement) {
            buffer.write('${variable.enclosingElement.name}.');
          }
          buffer.write('${variable.name}');
        } else {
          logger.error('Unsupported argument to initializer constructor.');
        }
      }
    } else if (expression is PropertyAccess) {
      buffer.write(buildExpression(expression.target, pluginData));
      buffer.write('.${expression.propertyName}');
    } else if (expression is InstanceCreationExpression) {
      logger.error('Unsupported expression in initializer, found $expression. '
          'Instance creation expressions are not supported (yet). Instead, '
          'please assign it to a const variable and use that instead.');
    } else {
      buffer.write(_evaluateExpression(expression, pluginData));
    }
    return buffer.toString();
  }

  _evaluateExpression(Expression expression, InitializerPluginData pluginData) {
    var logger = pluginData.logger;
    var result = pluginData.resolver.evaluateConstant(
        pluginData.initializer.targetElement.library, expression);
    if (!result.isValid) {
      logger.error('Invalid expression in initializer, found $expression. '
          'And got the following errors: ${result.errors}.');
      return null;
    }

    var value = _getValue(result.value);

    if (value == null) {
      logger.error('Unsupported expression in initializer, found '
          '$expression. Please file a bug at '
          'https://github.com/dart-lang/initialize/issues');
    }

    if (value is String) value = _stringValue(value);

    return value;
  }

  // Returns an expression for a string value. Wraps it in single quotes and
  // escapes existing single quotes and escapes.
  _stringValue(String value) {
    value = value.replaceAll(r'\', r'\\').replaceAll(r"'", r"\'");
    return "'$value'";
  }

  // Gets an actual value for a [DartObject].
  _getValue(DartObject object) {
    if (object == null) return null;
    var value = object.toBoolValue() ??
        object.toDoubleValue() ??
        object.toIntValue() ??
        object.toStringValue();
    if (value == null) {
      List list = object.toListValue();
      if (list != null) {
        return list.map((DartObject element) => _getValue(element)).toList();
      }
      Map<DartObject, DartObject> map = object.toMapValue();
      if (map != null) {
        Map result = {};
        map.forEach((DartObject key, DartObject value) {
          dynamic mappedKey = _getValue(key);
          if (mappedKey != null) {
            result[mappedKey] = _getValue(value);
          }
        });
        return result;
      }
    }
    return value;
  }
}
