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

import 'dart:async';
import 'dart:collection' show LinkedHashMap;
import 'package:barback/barback.dart';
import 'package:code_transformers/assets.dart';
import 'package:code_transformers/messages/build_logger.dart';
import 'package:html/dom.dart';
import 'package:html/dom_parsing.dart' show TreeVisitor;
import 'package:path/path.dart' as path;
import 'package:source_span/source_span.dart';
import 'common.dart';
import 'import_crawler.dart';
import 'messages.dart';

/// Transformer which inlines all html imports found from the entry points. This
/// deletes all dart scripts found during the inlining, so the
/// [ScriptCompactorTransformer] should be ran first if there are any dart files
/// in html imports.
class ImportInlinerTransformer extends Transformer {
  final List<String> entryPoints;
  final List<String> bindingStartDelimiters;

  ImportInlinerTransformer(
      [this.entryPoints, this.bindingStartDelimiters = const []]);

  bool isPrimary(AssetId id) {
    if (entryPoints != null) return entryPoints.contains(id.path);
    // If no entry point is supplied, then any html file under web/ or test/ is
    // an entry point.
    return (id.path.startsWith('web/') || id.path.startsWith('test/')) &&
        id.path.endsWith('.html');
  }

  apply(Transform transform) {
    var logger = new BuildLogger(transform, convertErrorsToWarnings: true);
    return new ImportInliner(transform, transform.primaryInput.id, logger,
        bindingStartDelimiters: bindingStartDelimiters).run();
  }
}

/// Helper class which actually does all the inlining of html imports for a
/// single entry point.
class ImportInliner {
  // Can be an AggregateTransform or Transform
  final transform;
  // The primary input to start from.
  final AssetId primaryInput;
  // The logger to use.
  final BuildLogger logger;
  // The start delimiters for template bindings, such as '{{' or '[['.
  final List<String> bindingStartDelimiters;

  ImportInliner(this.transform, this.primaryInput, this.logger,
      {this.bindingStartDelimiters: const []});

  Future run() {
    var crawler = new ImportCrawler(transform, primaryInput, logger);
    return crawler.crawlImports().then((imports) {
      var primaryDocument = imports[primaryInput].document;

      // Normalize urls in the entry point.
      var changed = new _UrlNormalizer(
              primaryInput, primaryInput, logger, bindingStartDelimiters)
          .visit(primaryDocument);

      // Inline things if needed, always have at least one (the entry point).
      if (imports.length > 1) {
        _inlineImports(primaryDocument, imports);
      } else if (!changed &&
          primaryDocument.querySelectorAll('link[rel="import"]').length == 0) {
        // If there were no url changes and no imports, then we are done.
        return;
      }

      primaryDocument
          .querySelectorAll('link[rel="import"]')
          .forEach((element) => element.remove());

      transform.addOutput(
          new Asset.fromString(primaryInput, primaryDocument.outerHtml));
    });
  }

  void _inlineImports(
      Document primaryDocument, LinkedHashMap<AssetId, ImportData> imports) {
    // Add a hidden div at the top of the body, this is where we will inline
    // all the imports.
    var importWrapper = new Element.tag('div')..attributes['hidden'] = '';
    var firstElement = primaryDocument.body.firstChild;
    if (firstElement != null) {
      primaryDocument.body.insertBefore(importWrapper, firstElement);
    } else {
      primaryDocument.body.append(importWrapper);
    }

    // Move all scripts/stylesheets/imports into the wrapper to maintain
    // ordering.
    _moveHeadToWrapper(primaryDocument, importWrapper);

    // Add all the other imports!
    imports.forEach((AssetId asset, ImportData data) {
      if (asset == primaryInput) return;
      var document = data.document;
      // Remove all dart script tags.
      document
          .querySelectorAll('script[type="$dartType"]')
          .forEach((script) => script.remove());
      // Normalize urls in attributes and inline css.
      new _UrlNormalizer(data.fromId, asset, logger, bindingStartDelimiters)
          .visit(document);
      // Replace the import with its contents by appending the nodes
      // immediately before the import one at a time, and then removing the
      // import from the document.
      var element = data.element;
      var parent = element.parent;
      document.head.nodes
          .toList(growable: false)
          .forEach((child) => parent.insertBefore(child, element));
      document.body.nodes
          .toList(growable: false)
          .forEach((child) => parent.insertBefore(child, element));
      element.remove();
    });
  }
}

/// To preserve the order of scripts with respect to inlined
/// link rel=import, we move both of those into the body before we do any
/// inlining. We do not start doing this until the first import is found
/// however, as some scripts do need to be ran in the head to work
/// properly (webcomponents.js for instance).
///
/// Note: we do this for stylesheets as well to preserve ordering with
/// respect to eachother, because stylesheets can be pulled in transitively
/// from imports.
void _moveHeadToWrapper(Document doc, Element wrapper) {
  var foundImport = false;
  for (var node in doc.head.nodes.toList(growable: false)) {
    if (node is! Element) continue;
    var tag = node.localName;
    var type = node.attributes['type'];
    var rel = node.attributes['rel'];
    if (tag == 'link' && rel == 'import') foundImport = true;
    if (!foundImport) continue;
    if (tag == 'style' ||
        tag == 'script' &&
            (type == null || type == jsType || type == dartType) ||
        tag == 'link' && (rel == 'stylesheet' || rel == 'import')) {
      // Move the node into the wrapper, where its contents will be placed.
      // This wrapper is a hidden div to prevent inlined html from causing a
      // FOUC.
      wrapper.append(node);
    }
  }
}

/// Internally adjusts urls in the html that we are about to inline.
// TODO(jakemac): Everything from here down is almost an exact copy from the
// polymer package. We should consolidate this logic by either removing it
// completely from polymer or exposing it publicly here and using that in
// polymer.
class _UrlNormalizer extends TreeVisitor {
  /// [AssetId] for the main entry point.
  final AssetId primaryInput;

  /// Asset where the original content (and original url) was found.
  final AssetId sourceId;

  /// Counter used to ensure that every library name we inject is unique.
  int _count = 0;

  /// Path to the top level folder relative to the transform primaryInput.
  /// This should just be some arbitrary # of ../'s.
  final String topLevelPath;

  /// Whether or not the normalizer has changed something in the tree.
  bool changed = false;

  // The start delimiters for template bindings, such as '{{' or '[['. If these
  // are found before the first `/` in a url, then the url will not be
  // normalized.
  final List<String> bindingStartDelimiters;

  final BuildLogger logger;

  _UrlNormalizer(AssetId primaryInput, this.sourceId, this.logger,
      this.bindingStartDelimiters)
      : primaryInput = primaryInput,
        topLevelPath = '../' * (path.url.split(primaryInput.path).length - 2);

  bool visit(Node node) {
    super.visit(node);
    return changed;
  }

  visitElement(Element node) {
    // TODO(jakemac): Support custom elements that extend html elements which
    // have url-like attributes. This probably means keeping a list of which
    // html elements support each url-like attribute.
    if (!isCustomTagName(node.localName)) {
      node.attributes.forEach((name, value) {
        if (_urlAttributes.contains(name)) {
          node.attributes[name] = _newUrl(value, node.sourceSpan);
          changed = value != node.attributes[name];
        }
      });
    }
    if (node.localName == 'style') {
      node.text = visitCss(node.text);
    } else if (node.localName == 'script' &&
        node.attributes['type'] == dartType &&
        !node.attributes.containsKey('src')) {
      changed = true;
    }
    return super.visitElement(node);
  }

  static final _url = new RegExp(r'url\(([^)]*)\)', multiLine: true);
  static final _quote = new RegExp('["\']', multiLine: true);

  /// Visit the CSS text and replace any relative URLs so we can inline it.
  // Ported from:
  // https://github.com/Polymer/vulcanize/blob/c14f63696797cda18dc3d372b78aa3378acc691f/lib/vulcan.js#L149
  // TODO(jmesserly): use csslib here instead? Parsing with RegEx is sadness.
  // Maybe it's reliable enough for finding URLs in CSS? I'm not sure.
  String visitCss(String cssText) {
    var url = spanUrlFor(sourceId, primaryInput, logger);
    var src = new SourceFile(cssText, url: url);
    return cssText.replaceAllMapped(_url, (match) {
      changed = true;
      // Extract the URL, without any surrounding quotes.
      var span = src.span(match.start, match.end);
      var href = match[1].replaceAll(_quote, '');
      href = _newUrl(href, span);
      return 'url($href)';
    });
  }

  String _newUrl(String href, SourceSpan span) {
    // We only want to parse the part of the href leading up to the first
    // folder, anything after that is not informative.
    var hrefToParse;
    var firstFolder = href.indexOf('/');
    if (firstFolder == -1) {
      hrefToParse = href;
    } else if (firstFolder == 0) {
      return href;
    } else {
      // Special case packages and assets urls.
      if (href.contains('packages/')) {
        var suffix = href.substring(href.indexOf('packages/') + 9);
        return '${topLevelPath}packages/$suffix';
      } else if (href.contains('assets/')) {
        var suffix = href.substring(href.indexOf('assets/') + 7);
        return '${topLevelPath}packages/$suffix';
      }

      hrefToParse = '${href.substring(0, firstFolder + 1)}';
    }

    // If we found a binding before the first `/`, then just return the original
    // href, we can't determine anything about it.
    if (bindingStartDelimiters.any((d) => hrefToParse.contains(d))) return href;

    Uri uri;
    // Various template systems introduce invalid characters to uris which would
    // be typically replaced at runtime. Parse errors are assumed to be caused
    // by this, and we just return the original href in that case.
    try {
      uri = Uri.parse(hrefToParse);
    } catch (e) {
      return href;
    }
    if (uri.isAbsolute) return href;
    if (uri.scheme.isNotEmpty) return href;
    if (uri.host.isNotEmpty) return href;
    if (uri.path.isEmpty) return href; // Implies standalone ? or # in URI.
    if (path.isAbsolute(hrefToParse)) return href;

    var id = uriToAssetId(sourceId, hrefToParse, logger, span);
    if (id == null) return href;

    // Build the new path, placing back any suffixes that we stripped earlier.
    var prefix =
        (firstFolder == -1) ? id.path : id.path.substring(0, id.path.length);
    var suffix = (firstFolder == -1) ? '' : href.substring(firstFolder);
    var newPath = '$prefix$suffix';

    if (newPath.startsWith('lib/')) {
      return '${topLevelPath}packages/${id.package}/${newPath.substring(4)}';
    }

    if (newPath.startsWith('asset/')) {
      return '${topLevelPath}assets/${id.package}/${newPath.substring(6)}';
    }

    if (primaryInput.package != id.package) {
      // Technically we shouldn't get there
      logger.error(internalErrorDontKnowHowToImport
              .create({'target': id, 'source': primaryInput, 'extra': ''}),
          span: span);
      return href;
    }

    var builder = path.url;
    return builder.normalize(builder.relative(builder.join('/', newPath),
        from: builder.join('/', builder.dirname(primaryInput.path))));
  }
}

/// Returns true if this is a valid custom element name. See:
/// <http://w3c.github.io/webcomponents/spec/custom/#dfn-custom-element-type>
bool isCustomTagName(String name) {
  if (name == null || !name.contains('-')) return false;
  return !invalidTagNames.containsKey(name);
}

/// These names have meaning in SVG or MathML, so they aren't allowed as custom
/// tags. See [isCustomTagName].
const invalidTagNames = const {
  'annotation-xml': '',
  'color-profile': '',
  'font-face': '',
  'font-face-src': '',
  'font-face-uri': '',
  'font-face-format': '',
  'font-face-name': '',
  'missing-glyph': '',
};

/// HTML attributes that expect a URL value.
/// <http://dev.w3.org/html5/spec/section-index.html#attributes-1>
///
/// Every one of these attributes is a URL in every context where it is used in
/// the DOM. The comments show every DOM element where an attribute can be used.
///
/// The _* version of each attribute is also supported, see http://goo.gl/5av8cU
const _urlAttributes = const [
  'action',
  '_action', // in form
  'background',
  '_background', // in body
  'cite',
  '_cite', // in blockquote, del, ins, q
  'data',
  '_data', // in object
  'formaction',
  '_formaction', // in button, input
  'href',
  '_href', // in a, area, link, base, command
  'icon',
  '_icon', // in command
  'manifest',
  '_manifest', // in html
  'poster',
  '_poster', // in video
  'src',
  '_src', // in audio, embed, iframe, img, input, script, source, track,video
];
