// 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 web_components.build.html_import_recorder_inliner;

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

/// [InitializerPlugin] for @HtmlImport annotations. This records all paths
/// seen, normalizes them relative to the entry point, and records the values in
/// [importPaths].
///
/// Note: This does nothing with the paths on its own, a separate step needs to
/// add the imports to the entry point document.
class HtmlImportAnnotationRecorder implements InitializerPlugin {
  /// All the normalized import paths that were seen.
  final Set<String> importPaths = new Set<String>();

  TransformLogger _logger;

  HtmlImportAnnotationRecorder();

  /// Applies to anything named `HtmlImport` which annotates a library.
  bool shouldApply(InitializerPluginData pluginData) {
    var annotationElement = pluginData.initializer.annotationNode.element;
    var logger = pluginData.logger;
    DartType type;
    if (annotationElement is ConstructorElement) {
      type = annotationElement.returnType;
    } else if (annotationElement is PropertyAccessorElement) {
      type = annotationElement.variable.propagatedType;
    } else {
      logger.error('Unsupported annotation type. Only constructors and '
          'properties are supported as initializers.');
      return false;
    }
    if (type.name != 'HtmlImport') return false;
    if (pluginData.initializer.targetElement is! LibraryElement) {
      logger.error('Invalid HtmlImport annotation on non-library element.');
      return false;
    }
    return true;
  }

  /// Records the normalized url and returns [null] so that no [InitEntry] will
  /// be created.
  String apply(InitializerPluginData pluginData) {
    var bootstrapId = pluginData.bootstrapId;
    var logger = pluginData.logger;
    var annotation = pluginData.initializer.annotationNode;
    var annotationElement = pluginData.initializer.annotationElement;
    var element = pluginData.initializer.targetElement as LibraryElement;
    var resolver = pluginData.resolver;
    var libraryDirective =
        pluginData.initializer.targetNode.parent.parent as LibraryDirective;

    var originalImportPath;
    if (annotationElement.element is PropertyAccessorElement) {
      originalImportPath = resolver.evaluateConstant(element.library,
          annotation.name).value.fields['filePath'].stringValue;
    } else {
      assert(annotationElement.element is ConstructorElement);
      originalImportPath = resolver.evaluateConstant(element.library,
          annotation.arguments.arguments.first).value.stringValue;
    }

    var libPath;
    var segments = element.source.uri.pathSegments;
    var package = segments[0];
    if (bootstrapId.package == package &&
        bootstrapId.path.startsWith('${segments[1]}/')) {
      package = null;
      libPath = 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') {
      libPath = path.url.joinAll(segments.getRange(2, segments.length));
    } else {
      logger.error('Unable to import `${element.source.uri.path}` from '
          '${bootstrapId}.');
      return null;
    }

    importPaths
        .add(normalizeHtmlImportPath(originalImportPath, package, libPath));

    // Don't emit an InitEntry.
    return null;
  }
}
