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

import 'dart:async';
import 'package:analyzer/analyzer.dart';
import 'package:barback/barback.dart';
import 'package:code_transformers/assets.dart';
import 'package:code_transformers/messages/build_logger.dart';
import 'package:html5lib/dom.dart' as dom;
import 'package:html5lib/parser.dart' as parser;
import 'package:path/path.dart' as path;
import 'package:source_maps/refactor.dart' show TextEditTransaction;
import 'package:source_span/source_span.dart';
import 'common.dart';
import 'import_crawler.dart';
import 'messages.dart';

/// Transformer which combines all dart scripts found in html imports into one
/// new bootstrap file, and replaces the old entry point script with that file.
///
/// Note: Does not delete the original script files (it can't because the
/// imports may live in other packages). The [ImportInlinerTransformer] will not
/// copy scripts when inlining imports into your entry point to compensate for
/// this.
class ScriptCompactorTransformer extends Transformer {
  final List<String> entryPoints;

  ScriptCompactorTransformer([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 ScriptCompactor(transform, transform.primaryInput.id, logger)
        .run()
        .then((Asset bootstrap) {
      if (bootstrap == null) return null;
      return transform.primaryInput.readAsString().then((html) {
        var doc = parser.parse(html);
        var mainScriptTag = doc.querySelector('script[type="$dartType"]');
        mainScriptTag.attributes['src'] =
            _importPath(bootstrap.id, transform.primaryInput.id);
        mainScriptTag.text = '';

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

/// Helper class which does all the script compacting for a single entry point.
class ScriptCompactor {
  /// Can be an AggregateTransform or Transform
  final transform;

  /// The primary input to start from.
  final AssetId primaryInput;

  /// The logger to use.
  final BuildLogger logger;

  /// How many inline scripts were extracted.
  int inlineScriptCounter = 0;

  /// Id representing the dart script which lives in the primaryInput.
  AssetId mainScript;

  /// Ids of all the scripts found in html imports.
  final Set<AssetId> importScripts = new Set<AssetId>();

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

  Future<Asset> run() {
    var crawler = new ImportCrawler(transform, primaryInput, logger);
    return crawler.crawlImports().then((imports) {
      Future extractScripts(id) =>
          _extractInlineScripts(id, imports[id].document);

      return Future.forEach(imports.keys, extractScripts).then((_) {
        if (mainScript == null) {
          logger.error(
              exactlyOneScriptPerEntryPoint.create({'url': primaryInput.path}));
          return null;
        }

        var primaryDocument = imports[primaryInput].document;
        assert(primaryDocument != null);

        // Create the new bootstrap file and return its AssetId.
        return _buildBootstrapFile(mainScript, importScripts);
      });
    });
  }

  /// Builds the bootstrap file and returns the path to it relative to
  /// [primaryInput].
  Asset _buildBootstrapFile(AssetId mainScript, Set<AssetId> importScripts) {
    var bootstrapId = new AssetId(mainScript.package,
        mainScript.path.replaceFirst('.dart', '.bootstrap.dart'));

    var buffer = new StringBuffer();
    buffer.writeln('library ${_libraryNameFor(bootstrapId)};');
    buffer.writeln();
    var i = 0;
    for (var script in importScripts) {
      var path = _importPath(script, primaryInput);
      buffer.writeln("import '$path' as i$i;");
      i++;
    }
    var mainScriptPath = _importPath(mainScript, primaryInput);
    buffer.writeln("import '$mainScriptPath' as i$i;");
    buffer.writeln();
    buffer.writeln('void main() { i$i.main(); }');

    var bootstrap = new Asset.fromString(bootstrapId, '$buffer');
    transform.addOutput(bootstrap);
    return bootstrap;
  }

  /// Split inline scripts into their own files. We need to do this for dart2js
  /// to be able to compile them.
  ///
  /// This also validates that there weren't any duplicate scripts.
  Future _extractInlineScripts(AssetId asset, dom.Document doc) {
    var scripts = doc.querySelectorAll('script[type="$dartType"]');
    return Future.forEach(scripts, (script) {
      var type = script.attributes['type'];
      var src = script.attributes['src'];

      if (src != null) {
        return _addScript(
            asset, uriToAssetId(asset, src, logger, script.sourceSpan),
            span: script.sourceSpan);
      }

      final count = inlineScriptCounter++;
      var code = script.text;
      // TODO(sigmund): ensure this path is unique (dartbug.com/12618).
      var newId = primaryInput.addExtension('.$count.dart');
      if (!_hasLibraryDirective(code)) {
        var libName = _libraryNameFor(primaryInput, count);
        code = "library $libName;\n$code";
      }

      // Normalize dart import paths.
      code = _normalizeDartImports(code, asset, primaryInput);

      // Write out the file and record it.
      transform.addOutput(new Asset.fromString(newId, code));

      return _addScript(asset, newId, validate: false).then((_) {
        // If in the entry point, replace the inline script with one pointing to
        // the new source file.
        if (primaryInput == asset) {
          script.text = '';
          script.attributes['src'] = path.url.relative(newId.path,
              from: path.url.dirname(primaryInput.path));
        }
      });
    });
  }

  // Normalize dart import paths when moving code from one asset to another.
  String _normalizeDartImports(String code, AssetId from, AssetId to) {
    var unit = parseDirectives(code, suppressErrors: true);
    var file = new SourceFile(code, url: spanUrlFor(from, to, logger));
    var output = new TextEditTransaction(code, file);
    var foundLibraryDirective = false;
    for (Directive directive in unit.directives) {
      if (directive is UriBasedDirective) {
        var uri = directive.uri.stringValue;
        var span = getSpan(file, directive.uri);

        var id = uriToAssetId(from, uri, logger, span, errorOnAbsolute: false);
        if (id == null) continue;

        var primaryId = primaryInput;
        var newUri = assetUrlFor(id, primaryId, logger);
        if (newUri != uri) {
          output.edit(span.start.offset, span.end.offset, "'$newUri'");
        }
      } else if (directive is LibraryDirective) {
        foundLibraryDirective = true;
      }
    }

    if (!output.hasEdits) return code;

    // TODO(sigmund): emit source maps when barback supports it (see
    // dartbug.com/12340)
    return (output.commit()..build(file.url.toString())).text;
  }

  Future _addScript(AssetId from, AssetId scriptId,
      {bool validate: true, SourceSpan span}) {
    var validateFuture;
    if (validate && !importScripts.contains(scriptId)) {
      validateFuture = transform.hasInput(scriptId);
    } else {
      validateFuture = new Future.value(true);
    }
    return validateFuture.then((exists) {
      if (!exists) {
        logger.warning(scriptFileNotFound.create({'url': scriptId}),
            span: span);
      }

      if (from == primaryInput) {
        if (mainScript != null) {
          logger
              .error(exactlyOneScriptPerEntryPoint.create({'url': from.path}));
        }
        mainScript = scriptId;
      } else {
        importScripts.add(scriptId);
      }
    });
  }
}

/// Generate a library name for an asset.
String _libraryNameFor(AssetId id, [int suffix]) {
  var name = '${path.withoutExtension(id.path)}_'
      '${path.extension(id.path).substring(1)}';
  if (name.startsWith('lib/')) name = name.substring(4);
  name = name.split('/').map((part) {
    part = part.replaceAll(_invalidLibCharsRegex, '_');
    if (part.startsWith(_numRegex)) part = '_${part}';
    return part;
  }).join(".");
  var suffixString = suffix != null ? '_$suffix' : '';
  return '${id.package}.${name}$suffixString';
}

/// Parse [code] and determine whether it has a library directive.
bool _hasLibraryDirective(String code) =>
    parseDirectives(code, suppressErrors: true).directives
        .any((d) => d is LibraryDirective);

/// Returns the dart import path to reach [id] relative to [primaryInput].
String _importPath(AssetId id, AssetId primaryInput) {
  var parts = path.url.split(id.path);
  if (parts[0] == 'lib') {
    parts[0] = id.package;
    return 'package:${path.url.joinAll(parts)}';
  }
  return path.url.relative(id.path, from: path.url.dirname(primaryInput.path));
}

// Constant and final variables
final _invalidLibCharsRegex = new RegExp('[^a-z0-9_]');
final _numRegex = new RegExp('[0-9]');
