// 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:html5lib/dom.dart';
import 'package:html5lib/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;

  ImportInlinerTransformer([this.entryPoints]);

  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)
        .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;

  ImportInliner(this.transform, this.primaryInput, this.logger);

  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)
          .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).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;

  final BuildLogger logger;

  _UrlNormalizer(AssetId primaryInput, this.sourceId, this.logger)
      : 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)}';
    }

    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
];
