// 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_annotation_inliner;

import 'dart:async';
import 'package:barback/barback.dart';
import 'package:html5lib/dom.dart' as dom;
import 'package:html5lib/parser.dart';
import '../src/normalize_path.dart';

/// Given an html entry point with a single dart bootstrap file created by the
/// `initialize` transformer, this will open that dart file and remove all
/// `HtmlImport` initializers from it. Then it appends those imports to the head
/// of the html entry point.
/// Note: Does not inline the import, it just puts the <link rel="import"> tag.
class HtmlImportAnnotationInliner extends AggregateTransformer {
  final String _bootstrapFile;
  final String _htmlEntryPoint;
  TransformLogger _logger;

  HtmlImportAnnotationInliner(this._bootstrapFile, this._htmlEntryPoint);

  factory HtmlImportAnnotationInliner.asPlugin(BarbackSettings settings) {
    var bootstrapFile = settings.configuration['bootstrap_file'];
    if (bootstrapFile is! String || !bootstrapFile.endsWith('.dart')) {
      throw new ArgumentError(
          '`bootstrap_file` should be a string path to a dart file');
    }
    var htmlEntryPoint = settings.configuration['html_entry_point'];
    if (htmlEntryPoint is! String || !htmlEntryPoint.endsWith('.html')) {
      throw new ArgumentError(
          '`html_entry_point` should be a string path to an html file');
    }
    return new HtmlImportAnnotationInliner(bootstrapFile, htmlEntryPoint);
  }

  classifyPrimary(AssetId id) {
    if (_bootstrapFile == id.path || _htmlEntryPoint == id.path) return ' ';
    return null;
  }

  Future apply(AggregateTransform transform) {
    _logger = transform.logger;
    Asset dartEntryPoint;
    Asset htmlEntryPoint;
    return transform.primaryInputs.take(2).listen((Asset asset) {
      if (asset.id.path == _bootstrapFile) dartEntryPoint = asset;
      if (asset.id.path == _htmlEntryPoint) htmlEntryPoint = asset;
    }).asFuture().then((_) {
      // Will be populated with all import paths found in HtmlImport
      // constructors.
      var importPaths;
      return dartEntryPoint.readAsString().then((dartCode) {
        var matches = _htmlImportWithRawString.allMatches(dartCode);
        importPaths = new Set.from(matches.map((match) =>
            normalizeHtmlImportPath(
                match.group(1),
                match.group(2) == 'null' ? null : match.group(2),
                match.group(3))));

        var newDartCode = dartCode.replaceAll(_htmlImportWithRawString, '');
        var leftoverMatches = _htmlImportGeneral.allMatches(newDartCode);
        for (var match in leftoverMatches) {
          _logger.warning('Found HtmlImport constructor which was supplied an '
              'expression. Only raw strings are currently supported: '
              '${match.group(0)}');
        }
        transform.addOutput(
            new Asset.fromString(dartEntryPoint.id, newDartCode));
      }).then((_) => htmlEntryPoint.readAsString()).then((html) {
        var doc = parse(html);
        for (var importPath in importPaths) {
          var import = new dom.Element.tag('link')..attributes = {
            'rel': 'import',
            'href': importPath,
          };
          doc.head.append(import);
        }
        transform.addOutput(
            new Asset.fromString(htmlEntryPoint.id, doc.outerHtml));
      });
    });
  }

  // Matches HtmlImport constructors which are supplied a raw string. These are
  // the only ones currently supported for inlining.
  final RegExp _htmlImportWithRawString = new RegExp(
      r"\n\s*new InitEntry\(const i[\d]*\.HtmlImport\('([\w\d\/\.:]*\.html)'\),"
      r"\sconst\sLibraryIdentifier\(#[\w\.]*, '?([\w_]*)'?, '([\w\d\/\.]*)'\)\)"
      r",");

  // Matches HtmlImport initializers which are supplied any arguments. This
  // is used to detect if any were left over and not inlined.
  final RegExp _htmlImportGeneral = new RegExp(
      r"\n\s*new InitEntry\(const i[\d]*\.HtmlImport\('([\w\.].*)'\),\s.*\),");
}
