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

part of csslib.visitor;

/// Visitor that produces a formatted string representation of the CSS tree.
class CssPrinter extends Visitor {
  StringBuffer _buff = new StringBuffer();
  bool prettyPrint = true;

  /// Walk the [tree] Stylesheet. [pretty] if true emits line breaks, extra
  /// spaces, friendly property values, etc., if false emits compacted output.
  void visitTree(StyleSheet tree, {bool pretty: false}) {
    prettyPrint = pretty;
    _buff = new StringBuffer();
    visitStyleSheet(tree);
  }

  /// Appends [str] to the output buffer.
  void emit(String str) {
    _buff.write(str);
  }

  /// Returns the output buffer.
  String toString() => _buff.toString().trim();

  String get _newLine => prettyPrint ? '\n' : '';
  String get _sp => prettyPrint ? ' ' : '';

  // TODO(terry): When adding obfuscation we'll need isOptimized (compact w/
  //              obufuscation) and have isTesting (compact no obfuscation) and
  //              isCompact would be !prettyPrint.  We'll need another boolean
  //              flag for obfuscation.
  bool get _isTesting => !prettyPrint;

  void visitCalcTerm(CalcTerm node) {
    emit('${node.text}(');
    node.expr.visit(this);
    emit(')');
  }

  void visitCssComment(CssComment node) {
    emit('/* ${node.comment} */');
  }

  void visitCommentDefinition(CommentDefinition node) {
    emit('<!-- ${node.comment} -->');
  }

  void visitMediaExpression(MediaExpression node) {
    emit(node.andOperator ? ' AND ' : ' ');
    emit('(${node.mediaFeature}');
    if (node.exprs.expressions.isNotEmpty) {
      emit(':');
      visitExpressions(node.exprs);
    }
    emit(')');
  }

  void visitMediaQuery(MediaQuery query) {
    var unary = query.hasUnary ? ' ${query.unary}' : '';
    var mediaType = query.hasMediaType ? ' ${query.mediaType}' : '';
    emit('$unary$mediaType');
    for (var expression in query.expressions) {
      visitMediaExpression(expression);
    }
  }

  void emitMediaQueries(List<MediaQuery> queries) {
    var queriesLen = queries.length;
    for (var i = 0; i < queriesLen; i++) {
      var query = queries[i];
      if (i > 0) emit(',');
      visitMediaQuery(query);
    }
  }

  void visitDocumentDirective(DocumentDirective node) {
    emit('$_newLine@-moz-document ');
    node.functions.first.visit(this);
    for (var function in node.functions.skip(1)) {
      emit(',$_sp');
      function.visit(this);
    }
    emit('$_sp{');
    for (var ruleSet in node.groupRuleBody) {
      ruleSet.visit(this);
    }
    emit('$_newLine}');
  }

  void visitSupportsDirective(SupportsDirective node) {
    emit('$_newLine@supports ');
    node.condition.visit(this);
    emit('$_sp{');
    for (var rule in node.groupRuleBody) {
      rule.visit(this);
    }
    emit('$_newLine}');
  }

  void visitSupportsConditionInParens(SupportsConditionInParens node) {
    emit('(');
    node.condition.visit(this);
    emit(')');
  }

  void visitSupportsNegation(SupportsNegation node) {
    emit('not$_sp');
    node.condition.visit(this);
  }

  void visitSupportsConjunction(SupportsConjunction node) {
    node.conditions.first.visit(this);
    for (var condition in node.conditions.skip(1)) {
      emit('${_sp}and$_sp');
      condition.visit(this);
    }
  }

  void visitSupportsDisjunction(SupportsDisjunction node) {
    node.conditions.first.visit(this);
    for (var condition in node.conditions.skip(1)) {
      emit('${_sp}or$_sp');
      condition.visit(this);
    }
  }

  void visitViewportDirective(ViewportDirective node) {
    emit('@${node.name}$_sp{$_newLine');
    node.declarations.visit(this);
    emit('}');
  }

  void visitMediaDirective(MediaDirective node) {
    emit('$_newLine@media');
    emitMediaQueries(node.mediaQueries);
    emit('$_sp{');
    for (var ruleset in node.rules) {
      ruleset.visit(this);
    }
    emit('$_newLine}');
  }

  void visitHostDirective(HostDirective node) {
    emit('$_newLine@host$_sp{');
    for (var ruleset in node.rules) {
      ruleset.visit(this);
    }
    emit('$_newLine}');
  }

  ///  @page : pseudoPage {
  ///    decls
  ///  }
  void visitPageDirective(PageDirective node) {
    emit('$_newLine@page');
    if (node.hasIdent || node.hasPseudoPage) {
      if (node.hasIdent) emit(' ');
      emit(node._ident);
      emit(node.hasPseudoPage ? ':${node._pseudoPage}' : '');
    }

    var declsMargin = node._declsMargin;
    var declsMarginLength = declsMargin.length;
    emit('$_sp{$_newLine');
    for (var i = 0; i < declsMarginLength; i++) {
      declsMargin[i].visit(this);
    }
    emit('}');
  }

  /// @charset "charset encoding"
  void visitCharsetDirective(CharsetDirective node) {
    emit('$_newLine@charset "${node.charEncoding}";');
  }

  void visitImportDirective(ImportDirective node) {
    bool isStartingQuote(String ch) => ('\'"'.indexOf(ch[0]) >= 0);

    if (_isTesting) {
      // Emit assuming url() was parsed; most suite tests use url function.
      emit(' @import url(${node.import})');
    } else if (isStartingQuote(node.import)) {
      emit(' @import ${node.import}');
    } else {
      // url(...) isn't needed only a URI can follow an @import directive; emit
      // url as a string.
      emit(' @import "${node.import}"');
    }
    emitMediaQueries(node.mediaQueries);
    emit(';');
  }

  void visitKeyFrameDirective(KeyFrameDirective node) {
    emit('$_newLine${node.keyFrameName} ');
    node.name.visit(this);
    emit('$_sp{$_newLine');
    for (final block in node._blocks) {
      block.visit(this);
    }
    emit('}');
  }

  void visitFontFaceDirective(FontFaceDirective node) {
    emit('$_newLine@font-face ');
    emit('$_sp{$_newLine');
    node._declarations.visit(this);
    emit('}');
  }

  void visitKeyFrameBlock(KeyFrameBlock node) {
    emit('$_sp$_sp');
    node._blockSelectors.visit(this);
    emit('$_sp{$_newLine');
    node._declarations.visit(this);
    emit('$_sp$_sp}$_newLine');
  }

  void visitStyletDirective(StyletDirective node) {
    emit('/* @stylet export as ${node.dartClassName} */\n');
  }

  void visitNamespaceDirective(NamespaceDirective node) {
    bool isStartingQuote(String ch) => ('\'"'.indexOf(ch) >= 0);

    if (isStartingQuote(node._uri)) {
      emit(' @namespace ${node.prefix}"${node._uri}"');
    } else {
      if (_isTesting) {
        // Emit exactly was we parsed.
        emit(' @namespace ${node.prefix}url(${node._uri})');
      } else {
        // url(...) isn't needed only a URI can follow a:
        //    @namespace prefix directive.
        emit(' @namespace ${node.prefix}${node._uri}');
      }
    }
    emit(';');
  }

  void visitVarDefinitionDirective(VarDefinitionDirective node) {
    visitVarDefinition(node.def);
    emit(';$_newLine');
  }

  void visitMixinRulesetDirective(MixinRulesetDirective node) {
    emit('@mixin ${node.name} {');
    for (var ruleset in node.rulesets) {
      ruleset.visit(this);
    }
    emit('}');
  }

  void visitMixinDeclarationDirective(MixinDeclarationDirective node) {
    emit('@mixin ${node.name} {\n');
    visitDeclarationGroup(node.declarations);
    emit('}');
  }

  /// Added optional newLine for handling @include at top-level vs/ inside of
  /// a declaration group.
  void visitIncludeDirective(IncludeDirective node, [bool topLevel = true]) {
    if (topLevel) emit(_newLine);
    emit('@include ${node.name}');
    emit(';');
  }

  void visitContentDirective(ContentDirective node) {
    // TODO(terry): TBD
  }

  void visitRuleSet(RuleSet node) {
    emit("$_newLine");
    node._selectorGroup.visit(this);
    emit("$_sp{$_newLine");
    node._declarationGroup.visit(this);
    emit("}");
  }

  void visitDeclarationGroup(DeclarationGroup node) {
    var declarations = node.declarations;
    var declarationsLength = declarations.length;
    for (var i = 0; i < declarationsLength; i++) {
      if (i > 0) emit(_newLine);
      emit("$_sp$_sp");
      declarations[i].visit(this);
      // Don't emit the last semicolon in compact mode.
      if (prettyPrint || i < declarationsLength - 1) {
        emit(';');
      }
    }
    if (declarationsLength > 0) emit(_newLine);
  }

  void visitMarginGroup(MarginGroup node) {
    var margin_sym_name =
        TokenKind.idToValue(TokenKind.MARGIN_DIRECTIVES, node.margin_sym);

    emit("@$margin_sym_name$_sp{$_newLine");

    visitDeclarationGroup(node);

    emit("}$_newLine");
  }

  void visitDeclaration(Declaration node) {
    emit('${node.property}:$_sp');
    node._expression.visit(this);
    if (node.important) {
      emit('$_sp!important');
    }
  }

  void visitVarDefinition(VarDefinition node) {
    emit("var-${node.definedName}: ");
    node._expression.visit(this);
  }

  void visitIncludeMixinAtDeclaration(IncludeMixinAtDeclaration node) {
    // Don't emit a new line we're inside of a declaration group.
    visitIncludeDirective(node.include, false);
  }

  void visitExtendDeclaration(ExtendDeclaration node) {
    emit("@extend ");
    for (var selector in node.selectors) {
      selector.visit(this);
    }
  }

  void visitSelectorGroup(SelectorGroup node) {
    var selectors = node.selectors;
    var selectorsLength = selectors.length;
    for (var i = 0; i < selectorsLength; i++) {
      if (i > 0) emit(',$_sp');
      selectors[i].visit(this);
    }
  }

  void visitSimpleSelectorSequence(SimpleSelectorSequence node) {
    emit('${node._combinatorToString}');
    node.simpleSelector.visit(this);
  }

  void visitSimpleSelector(SimpleSelector node) {
    emit(node.name);
  }

  void visitNamespaceSelector(NamespaceSelector node) {
    emit(node.toString());
  }

  void visitElementSelector(ElementSelector node) {
    emit(node.toString());
  }

  void visitAttributeSelector(AttributeSelector node) {
    emit(node.toString());
  }

  void visitIdSelector(IdSelector node) {
    emit(node.toString());
  }

  void visitClassSelector(ClassSelector node) {
    emit(node.toString());
  }

  void visitPseudoClassSelector(PseudoClassSelector node) {
    emit(node.toString());
  }

  void visitPseudoElementSelector(PseudoElementSelector node) {
    emit(node.toString());
  }

  void visitPseudoClassFunctionSelector(PseudoClassFunctionSelector node) {
    emit(":${node.name}(");
    node.argument.visit(this);
    emit(')');
  }

  void visitPseudoElementFunctionSelector(PseudoElementFunctionSelector node) {
    emit("::${node.name}(");
    node.expression.visit(this);
    emit(')');
  }

  void visitNegationSelector(NegationSelector node) {
    emit(':not(');
    node.negationArg.visit(this);
    emit(')');
  }

  void visitSelectorExpression(SelectorExpression node) {
    var expressions = node.expressions;
    var expressionsLength = expressions.length;
    for (var i = 0; i < expressionsLength; i++) {
      // Add space seperator between terms without an operator.
      var expression = expressions[i];
      expression.visit(this);
    }
  }

  void visitUnicodeRangeTerm(UnicodeRangeTerm node) {
    if (node.hasSecond) {
      emit("U+${node.first}-${node.second}");
    } else {
      emit("U+${node.first}");
    }
  }

  void visitLiteralTerm(LiteralTerm node) {
    emit(node.text);
  }

  void visitHexColorTerm(HexColorTerm node) {
    var mappedName;
    if (_isTesting && (node.value is! BAD_HEX_VALUE)) {
      mappedName = TokenKind.hexToColorName(node.value);
    }
    if (mappedName == null) {
      mappedName = '#${node.text}';
    }

    emit(mappedName);
  }

  void visitNumberTerm(NumberTerm node) {
    visitLiteralTerm(node);
  }

  void visitUnitTerm(UnitTerm node) {
    emit(node.toString());
  }

  void visitLengthTerm(LengthTerm node) {
    emit(node.toString());
  }

  void visitPercentageTerm(PercentageTerm node) {
    emit('${node.text}%');
  }

  void visitEmTerm(EmTerm node) {
    emit('${node.text}em');
  }

  void visitExTerm(ExTerm node) {
    emit('${node.text}ex');
  }

  void visitAngleTerm(AngleTerm node) {
    emit(node.toString());
  }

  void visitTimeTerm(TimeTerm node) {
    emit(node.toString());
  }

  void visitFreqTerm(FreqTerm node) {
    emit(node.toString());
  }

  void visitFractionTerm(FractionTerm node) {
    emit('${node.text}fr');
  }

  void visitUriTerm(UriTerm node) {
    emit('url("${node.text}")');
  }

  void visitResolutionTerm(ResolutionTerm node) {
    emit(node.toString());
  }

  void visitViewportTerm(ViewportTerm node) {
    emit(node.toString());
  }

  void visitFunctionTerm(FunctionTerm node) {
    // TODO(terry): Optimize rgb to a hexcolor.
    emit('${node.text}(');
    node._params.visit(this);
    emit(')');
  }

  void visitGroupTerm(GroupTerm node) {
    emit('(');
    var terms = node._terms;
    var termsLength = terms.length;
    for (var i = 0; i < termsLength; i++) {
      if (i > 0) emit('$_sp');
      terms[i].visit(this);
    }
    emit(')');
  }

  void visitItemTerm(ItemTerm node) {
    emit('[${node.text}]');
  }

  void visitIE8Term(IE8Term node) {
    visitLiteralTerm(node);
  }

  void visitOperatorSlash(OperatorSlash node) {
    emit('/');
  }

  void visitOperatorComma(OperatorComma node) {
    emit(',');
  }

  void visitOperatorPlus(OperatorPlus node) {
    emit('+');
  }

  void visitOperatorMinus(OperatorMinus node) {
    emit('-');
  }

  void visitVarUsage(VarUsage node) {
    emit('var(${node.name}');
    if (node.defaultValues.isNotEmpty) {
      emit(',');
      for (var defaultValue in node.defaultValues) {
        emit(' ');
        defaultValue.visit(this);
      }
    }
    emit(')');
  }

  void visitExpressions(Expressions node) {
    var expressions = node.expressions;
    var expressionsLength = expressions.length;
    for (var i = 0; i < expressionsLength; i++) {
      // Add space seperator between terms without an operator.
      // TODO(terry): Should have a BinaryExpression to solve this problem.
      var expression = expressions[i];
      if (i > 0 &&
          !(expression is OperatorComma || expression is OperatorSlash)) {
        // If the previous expression is an operator, use `_sp` so the space is
        // collapsed when emitted in compact mode. If the previous expression
        // isn't an operator, the space is significant to delimit the two
        // expressions and can't be collapsed.
        var previous = expressions[i - 1];
        if (previous is OperatorComma || previous is OperatorSlash) {
          emit(_sp);
        } else {
          emit(' ');
        }
      }
      expression.visit(this);
    }
  }

  void visitBinaryExpression(BinaryExpression node) {
    // TODO(terry): TBD
    throw UnimplementedError;
  }

  void visitUnaryExpression(UnaryExpression node) {
    // TODO(terry): TBD
    throw UnimplementedError;
  }

  void visitIdentifier(Identifier node) {
    emit(node.name);
  }

  void visitWildcard(Wildcard node) {
    emit('*');
  }

  void visitDartStyleExpression(DartStyleExpression node) {
    // TODO(terry): TBD
    throw UnimplementedError;
  }
}
