// 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);
    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(transform, 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(transform, 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 {
  final Transform transform;

  /// 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(transform, this.sourceId, this.logger)
      : transform = transform,
        topLevelPath = '../' *
            (transform.primaryInput.id.path.split('/').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, transform.primaryInput.id, 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;
    var primaryId = transform.primaryInput.id;

    // 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 (primaryId.package != id.package) {
      // Technically we shouldn't get there
      logger.error(internalErrorDontKnowHowToImport
              .create({'target': id, 'source': primaryId, 'extra': ''}),
          span: span);
      return href;
    }

    var builder = path.url;
    return path.normalize(builder.relative(builder.join('/', newPath),
        from: builder.join('/', builder.dirname(primaryId.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
];
