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

/**
 * Logic to validate that developers are correctly using Polymer constructs.
 * This is mainly used to produce warnings for feedback in the editor.
 */
library polymer.src.build.linter;

import 'dart:io';
import 'dart:async';
import 'dart:mirrors';
import 'dart:convert' show JSON;

import 'package:barback/barback.dart';
import 'package:html5lib/dom.dart';
import 'package:html5lib/dom_parsing.dart';
import 'package:source_maps/span.dart';

import 'common.dart';
import 'utils.dart';

typedef String MessageFormatter(String kind, String message, Span span);

/**
 * A linter that checks for common Polymer errors and produces warnings to
 * show on the editor or the command line. Leaves sources unchanged, but creates
 * a new asset containing all the warnings.
 */
class Linter extends Transformer with PolymerTransformer {
  final TransformOptions options;

  /** Only run on .html files. */
  final String allowedExtensions = '.html';

  final MessageFormatter _formatter;

  Linter(this.options, [this._formatter]);

  Future apply(Transform transform) {
    var wrapper = new _LoggerInterceptor(transform, _formatter);
    var seen = new Set<AssetId>();
    var primary = transform.primaryInput;
    var id = primary.id;
    wrapper.addOutput(primary); // this phase is analysis only
    seen.add(id);
    return readPrimaryAsHtml(wrapper).then((document) {
      return _collectElements(document, id, wrapper, seen).then((elements) {
        new _LinterVisitor(wrapper, elements).visit(document);
        var messagesId = id.addExtension('.messages');
        wrapper.addOutput(new Asset.fromString(messagesId,
            wrapper._messages.join('\n')));
      });
    });
  }

  /**
   * Collect into [elements] any data about each polymer-element defined in
   * [document] or any of it's imports, unless they have already been [seen].
   * Elements are added in the order they appear, transitive imports are added
   * first.
   */
  Future<Map<String, _ElementSummary>> _collectElements(
      Document document, AssetId sourceId, Transform transform,
      Set<AssetId> seen, [Map<String, _ElementSummary> elements]) {
    if (elements == null) elements = <String, _ElementSummary>{};
    return _getImportedIds(document, sourceId, transform)
        // Note: the import order is relevant, so we visit in that order.
        .then((ids) => Future.forEach(ids,
              (id) => _readAndCollectElements(id, transform, seen, elements)))
        .then((_) => _addElements(document, transform.logger, elements))
        .then((_) => elements);
  }

  Future _readAndCollectElements(AssetId id, Transform transform,
      Set<AssetId> seen, Map<String, _ElementSummary> elements) {
    if (id == null || seen.contains(id)) return new Future.value(null);
    seen.add(id);
    return readAsHtml(id, transform).then(
        (doc) => _collectElements(doc, id, transform, seen, elements));
  }

  Future<List<AssetId>> _getImportedIds(
      Document document, AssetId sourceId, Tranform transform) {
    var importIds = [];
    var logger = transform.logger;
    for (var tag in document.queryAll('link')) {
      if (tag.attributes['rel'] != 'import') continue;
      var href = tag.attributes['href'];
      var span = tag.sourceSpan;
      var id = resolve(sourceId, href, logger, span);
      if (id == null) continue;
      importIds.add(assetExists(id, transform).then((exists) {
        if (exists) return id;
        if (sourceId == transform.primaryInput.id) {
          logger.error('couldn\'t find imported asset "${id.path}" in package '
              '"${id.package}".', span);
        }
      }));
    }
    return Future.wait(importIds);
  }

  void _addElements(Document document, TransformLogger logger,
      Map<String, _ElementSummary> elements) {
    for (var tag in document.queryAll('polymer-element')) {
      var name = tag.attributes['name'];
      if (name == null) continue;
      var extendsTag = tag.attributes['extends'];
      var span = tag.sourceSpan;
      var existing = elements[name];
      if (existing != null) {

        // Report warning only once.
        if (existing.hasConflict) continue;
        existing.hasConflict = true;
        logger.warning('duplicate definition for custom tag "$name".',
          existing.span);
        logger.warning('duplicate definition for custom tag "$name" '
          ' (second definition).', span);
        continue;
      }

      elements[name] = new _ElementSummary(name, extendsTag, tag.sourceSpan);
    }
  }
}

/** A proxy of [Transform] that returns a different logger. */
// TODO(sigmund): get rid of this when barback supports a better way to log
// messages without printing them.
class _LoggerInterceptor implements Transform, TransformLogger {
  final Transform _original;
  final List<String> _messages = [];
  final MessageFormatter _formatter;

  _LoggerInterceptor(this._original, MessageFormatter formatter)
      : _formatter = formatter == null ? consoleFormatter : formatter;

  TransformLogger get logger => this;

  noSuchMethod(Invocation m) => reflect(_original).delegate(m);

  // form TransformLogger:
  void warning(String message, [Span span]) => _write('warning', message, span);

  void error(String message, [Span span]) => _write('error', message, span);

  void _write(String kind, String message, Span span) {
    _messages.add(_formatter(kind, message, span));
  }
}

/**
 * Formatter that generates messages using a format that can be parsed
 * by tools, such as the Dart Editor, for reporting error messages.
 */
String jsonFormatter(String kind, String message, Span span) {
  return JSON.encode((span == null)
      ? [{'method': 'warning', 'params': {'message': message}}]
      : [{'method': kind,
          'params': {
            'file': span.sourceUrl,
            'message': message,
            'line': span.start.line + 1,
            'charStart': span.start.offset,
            'charEnd': span.end.offset,
          }}]);
}

/**
 * Formatter that generates messages that are easy to read on the console (used
 * by default).
 */
String consoleFormatter(String kind, String message, Span span) {
  var useColors = stdioType(stdout) == StdioType.TERMINAL;
  var levelColor = (kind == 'error') ? _RED_COLOR : _MAGENTA_COLOR;
  var output = new StringBuffer();
  if (useColors) output.write(levelColor);
  output..write(kind)..write(' ');
  if (useColors) output.write(_NO_COLOR);
  if (span == null) {
    output.write(message);
  } else {
    output.write(span.getLocationMessage(message,
          useColors: useColors,
          color: levelColor));
  }
  return output.toString();
}

/**
 * Information needed about other polymer-element tags in order to validate
 * how they are used and extended.
 *
 * Note: these are only created for polymer-element, because pure custom
 * elements don't have a declarative form.
 */
class _ElementSummary {
  final String tagName;
  final String extendsTag;
  final Span span;

  _ElementSummary extendsType;
  bool hasConflict = false;

  String get baseExtendsTag => extendsType == null
      ? extendsTag : extendsType.baseExtendsTag;

  _ElementSummary(this.tagName, this.extendsTag, this.span);

  String toString() => "($tagName <: $extendsTag)";
}

class _LinterVisitor extends TreeVisitor {
  TransformLogger _logger;
  bool _inPolymerElement = false;
  Map<String, _ElementSummary> _elements;

  _LinterVisitor(this._logger, this._elements) {
    // We normalize the map, so each element has a direct reference to any
    // element it extends from.
    for (var tag in _elements.values) {
      var extendsTag = tag.extendsTag;
      if (extendsTag == null) continue;
      tag.extendsType = _elements[extendsTag];
    }
  }

  void visitElement(Element node) {
    switch (node.tagName) {
      case 'link': _validateLinkElement(node); break;
      case 'element': _validateElementElement(node); break;
      case 'polymer-element': _validatePolymerElement(node); break;
      case 'script': _validateScriptElement(node); break;
      default:
         _validateNormalElement(node);
         super.visitElement(node);
         break;
    }
  }

  /** Produce warnings for invalid link-rel tags. */
  void _validateLinkElement(Element node) {
    var rel = node.attributes['rel'];
    if (rel != 'import' && rel != 'stylesheet') return;

    var href = node.attributes['href'];
    if (href != null && href != '') return;

    // TODO(sigmund): warn also if href can't be resolved.
    _logger.warning('link rel="$rel" missing href.', node.sourceSpan);
  }

  /** Produce warnings if using `<element>` instead of `<polymer-element>`. */
  void _validateElementElement(Element node) {
    _logger.warning('<element> elements are not supported, use'
        ' <polymer-element> instead', node.sourceSpan);
  }

  /**
   * Produce warnings if using `<polymer-element>` in the wrong place or if the
   * definition is not complete.
   */
  void _validatePolymerElement(Element node) {
    if (_inPolymerElement) {
      _logger.error('Nested polymer element definitions are not allowed.',
          node.sourceSpan);
      return;
    }

    var tagName = node.attributes['name'];
    var extendsTag = node.attributes['extends'];

    if (tagName == null) {
      _logger.error('Missing tag name of the custom element. Please include an '
          'attribute like \'name="your-tag-name"\'.',
          node.sourceSpan);
    } else if (!_isCustomTag(tagName)) {
      _logger.error('Invalid name "$tagName". Custom element names must have '
          'at least one dash and can\'t be any of the following names: '
          '${_invalidTagNames.keys.join(", ")}.',
          node.sourceSpan);
    }

    if (_elements[extendsTag] == null && _isCustomTag(extendsTag)) {
      _logger.warning('custom element with name "$extendsTag" not found.',
          node.sourceSpan);
    }

    var attrs = node.attributes['attributes'];
    if (attrs != null) {
      var attrsSpan = node.attributeSpans['attributes'];

      // names='a b c' or names='a,b,c'
      // record each name for publishing
      for (var attr in attrs.split(attrs.contains(',') ? ',' : ' ')) {
        // remove excess ws
        attr = attr.trim();
        if (!_validateCustomAttributeName(attr, attrsSpan)) break;
      }
    }

    var oldValue = _inPolymerElement;
    _inPolymerElement = true;
    super.visitElement(node);
    _inPolymerElement = oldValue;
  }

  /**
   * Produces warnings for malformed script tags. In html5 leaving off type= is
   * fine, but it defaults to text/javascript. Because this might be a common
   * error, we warn about it when  src file ends in .dart, but the type is
   * incorrect, or when users write code in an inline script tag of a custom
   * element.
   *
   * The hope is that these cases shouldn't break existing valid code, but that
   * they'll help Polymer authors avoid having their Dart code accidentally
   * interpreted as JavaScript by the browser.
   */
  void _validateScriptElement(Element node) {
    var scriptType = node.attributes['type'];
    var src = node.attributes['src'];

    if (scriptType == null) {
      if (src == null && _inPolymerElement) {
        // TODO(sigmund): revisit this check once we start interop with polymer
        // elements written in JS. Maybe we need to inspect the contents of the
        // script to find whether there is an import or something that indicates
        // that the code is indeed using Dart.
        _logger.warning('script tag in polymer element with no type will '
            'be treated as JavaScript. Did you forget type="application/dart"?',
            node.sourceSpan);
      }
      if (src != null && src.endsWith('.dart')) {
        _logger.warning('script tag with .dart source file but no type will '
            'be treated as JavaScript. Did you forget type="application/dart"?',
            node.sourceSpan);
      }
      return;
    }

    if (scriptType != 'application/dart') return;

    if (src != null) {
      if (!src.endsWith('.dart')) {
        _logger.warning('"application/dart" scripts should '
            'use the .dart file extension.',
            node.sourceSpan);
      }

      if (node.innerHtml.trim() != '') {
        _logger.warning('script tag has "src" attribute and also has script '
            'text.', node.sourceSpan);
      }
    }
  }

  /**
   * Produces warnings for misuses of on-foo event handlers, and for instanting
   * custom tags incorrectly.
   */
  void _validateNormalElement(Element node) {
    // Event handlers only allowed inside polymer-elements
    node.attributes.forEach((name, value) {
      if (name.startsWith('on')) {
        _validateEventHandler(node, name, value);
      }
    });

    // Validate uses of custom-tags
    var nodeTag = node.tagName;
    var hasIsAttribute;
    var customTagName;
    if (_isCustomTag(nodeTag)) {
      // <fancy-button>
      customTagName = nodeTag;
      hasIsAttribute = false;
    } else {
      // <button is="fancy-button">
      customTagName = node.attributes['is'];
      hasIsAttribute = true;
    }

    if (customTagName == null || customTagName == 'polymer-element') return;

    var info = _elements[customTagName];
    if (info == null) {
      // TODO(jmesserly): this warning is wrong if someone is using raw custom
      // elements. Is there another way we can handle this warning that won't
      // generate false positives?
      _logger.warning('definition for Polymer element with tag name '
          '"$customTagName" not found.', node.sourceSpan);
      return;
    }

    var baseTag = info.baseExtendsTag;
    if (baseTag != null && !hasIsAttribute) {
      _logger.warning(
          'custom element "$customTagName" extends from "$baseTag", but '
          'this tag will not include the default properties of "$baseTag". '
          'To fix this, either write this tag as <$baseTag '
          'is="$customTagName"> or remove the "extends" attribute from '
          'the custom element declaration.', node.sourceSpan);
      return;
    }

    if (hasIsAttribute && baseTag == null) {
      _logger.warning(
          'custom element "$customTagName" doesn\'t declare any type '
          'extensions. To fix this, either rewrite this tag as '
          '<$customTagName> or add \'extends="$nodeTag"\' to '
          'the custom element declaration.', node.sourceSpan);
      return;
    }

    if (hasIsAttribute && baseTag != nodeTag) {
      _logger.warning(
          'custom element "$customTagName" extends from "$baseTag". '
          'Did you mean to write <$baseTag is="$customTagName">?',
          node.sourceSpan);
    }
  }

  /**
   * Validate an attribute on a custom-element. Returns true if valid.
   */
  bool _validateCustomAttributeName(String name, FileSpan span) {
    if (name.contains('-')) {
      var newName = toCamelCase(name);
      _logger.warning('PolymerElement no longer recognizes attribute names with '
          'dashes such as "$name". Use "$newName" or "${newName.toLowerCase()}" '
          'instead (both forms are equivalent in HTML).', span);
      return false;
    }
    return true;
  }

  /** Validate event handlers are used correctly. */
  void _validateEventHandler(Element node, String name, String value) {
    if (!name.startsWith('on-')) {
      _logger.warning('Event handler "$name" will be interpreted as an inline'
          ' JavaScript event handler. Use the form '
          'on-event-name="handlerName" if you want a Dart handler '
          'that will automatically update the UI based on model changes.',
          node.attributeSpans[name]);
      return;
    }

    if (!_inPolymerElement) {
      _logger.warning('Inline event handlers are only supported inside '
          'declarations of <polymer-element>.', node.attributeSpans[name]);
    }

    var eventName = name.substring('on-'.length);
    if (eventName.contains('-')) {
      var newEvent = toCamelCase(eventName);
      _logger.warning('Invalid event name "$name". After the "on-" the event '
          'name should not use dashes. For example use "on-$newEvent" or '
          '"on-${newEvent.toLowerCase()}" (both forms are equivalent in HTML).',
          node.attributeSpans[name]);
    }

    if (value.contains('.') || value.contains('(')) {
      _logger.warning('Invalid event handler body "$value". Declare a method '
          'in your custom element "void handlerName(event, detail, target)" '
          'and use the form $name="handlerName".',
          node.attributeSpans[name]);
    }
  }
}


// These names have meaning in SVG or MathML, so they aren't allowed as custom
// tags.
var _invalidTagNames = const {
  'annotation-xml': '',
  'color-profile': '',
  'font-face': '',
  'font-face-src': '',
  'font-face-uri': '',
  'font-face-format': '',
  'font-face-name': '',
  'missing-glyph': '',
};

/**
 * Returns true if this is a valid custom element name. See:
 * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-custom-element-name>
 */
bool _isCustomTag(String name) {
  if (name == null || !name.contains('-')) return false;
  return !_invalidTagNames.containsKey(name);
}

final String _RED_COLOR = '\u001b[31m';
final String _MAGENTA_COLOR = '\u001b[35m';
final String _NO_COLOR = '\u001b[0m';
