// 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:html/dom.dart' as dom;
import 'package:html/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(primaryInput.package,
        primaryInput.path.replaceFirst('.html', '.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('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]');
