// Copyright (c) 2013, 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_crawler;

import 'dart:async';
import 'dart:collection' show LinkedHashMap;
import 'package:code_transformers/assets.dart';
import 'package:code_transformers/messages/build_logger.dart';
import 'package:barback/barback.dart';
import 'package:html5lib/dom.dart' show Document, Element;
import 'common.dart';
import 'messages.dart';

/// Information about an html import found in a document.
class ImportData {
  /// The [AssetId] where the html import appeared.
  final AssetId fromId;

  /// The [Document] where the html import appeared.
  final Document document;

  /// The html import element itself.
  final Element element;

  ImportData(this.document, this.element, {this.fromId});
}

/// A crawler for html imports.
class ImportCrawler {
  // Can be either an AggregateTransform or Transform.
  final _transform;
  final BuildLogger _logger;
  final AssetId _primaryInputId;

  // Optional parsed document for the primary id if available.
  final Document _primaryDocument;

  ImportCrawler(this._transform, this._primaryInputId, this._logger,
      {Document primaryDocument})
      : _primaryDocument = primaryDocument;

  /// Returns a post-ordered map of [AssetId]'s to [ImportData]. The [AssetId]'s
  /// represent an asset which was discovered via an html import, and the
  /// [ImportData] represents the [Document] where it was discovered and the
  /// html import [Element] itself.
  Future<LinkedHashMap<AssetId, ImportData>> crawlImports() {
    var documents = new LinkedHashMap<AssetId, ImportData>();
    var seen = new Set<AssetId>();

    Future doCrawl(AssetId assetId,
        {Element import, Document document, AssetId from}) {
      if (seen.contains(assetId)) return null;
      seen.add(assetId);

      Future crawlImports(Document document) {
        var imports = document.querySelectorAll('link[rel="import"]');
        var done = Future.forEach(imports,
            (i) => doCrawl(_importId(assetId, i), import: i, from: assetId));

        // Add this document after its dependencies.
        return done.then((_) {
          documents[assetId] = new ImportData(document, import, fromId: from);
        });
      }

      if (document != null) {
        return crawlImports(document);
      } else {
        return _transform.readInputAsString(assetId).then((html) {
          return crawlImports(parseHtml(html, assetId.path));
        }).catchError((error) {
          var span;
          if (import != null) span = import.sourceSpan;
          _logger.error(inlineImportFail.create({'error': error}), span: span);
        });
      }
    }

    return doCrawl(_primaryInputId, document: _primaryDocument)
        .then((_) => documents);
  }

  AssetId _importId(AssetId source, Element import) {
    var url = import.attributes['href'];
    return uriToAssetId(source, url, _transform.logger, import.sourceSpan);
  }
}
