// Copyright (c) 2014, 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.

// @dart=2.12

part of dart2js.util;

/// Indentation utility class. Should be used as a mixin in most cases.
class Indentation {
  /// The current indentation string.
  String get indentation {
    // Lazily add new indentation strings as required.
    for (int i = _indentList.length; i <= _indentLevel; i++) {
      _indentList.add(_indentList[i - 1] + indentationUnit);
    }
    return _indentList[_indentLevel];
  }

  /// The current indentation level.
  int _indentLevel = 0;

  /// A cache of all indentation strings used so far.
  /// Always at least of length 1.
  List<String> _indentList = <String>[""];

  /// The indentation unit, defaulting to two spaces. May be overwritten.
  String _indentationUnit = "  ";
  String get indentationUnit => _indentationUnit;
  set indentationUnit(String value) {
    if (value != _indentationUnit) {
      _indentationUnit = value;
      _indentList = <String>[""];
    }
  }

  /// Increases the current level of indentation.
  void indentMore() {
    _indentLevel++;
  }

  /// Decreases the current level of indentation.
  void indentLess() {
    _indentLevel--;
  }

  /// Calls [f] with one more indentation level, restoring indentation context
  /// upon return of [f] and returning its result.
  indentBlock(Function f) {
    indentMore();
    var result = f();
    indentLess();
    return result;
  }
}

abstract class Tagging<N> implements Indentation {
  StringBuffer sb = new StringBuffer();
  Link<String> tagStack = const Link<String>();

  void pushTag(String tag) {
    tagStack = tagStack.prepend(tag);
    indentMore();
  }

  String popTag() {
    assert(!tagStack.isEmpty);
    String tag = tagStack.head;
    tagStack = tagStack.tail!;
    indentLess();
    return tag;
  }

  /// Adds given string to result string.
  void add(String string) {
    sb.write(string);
  }

  /// Adds default parameters for [node] into [params].
  void addDefaultParameters(N node, Map params) {}

  /// Adds given node type to result string.
  /// The method "opens" the node, meaning that all output after calling
  /// this method and before calling closeNode() will represent contents
  /// of given node.
  void openNode(N node, String type, [Map? params]) {
    if (params == null) params = new Map();
    addCurrentIndent();
    sb.write("<");
    addDefaultParameters(node, params);
    addTypeWithParams(type, params);
    sb.write(">\n");
    pushTag(type);
  }

  /// Adds given node to result string.
  void openAndCloseNode(N node, String type, [Map? params]) {
    if (params == null) params = {};
    addCurrentIndent();
    sb.write("<");
    addDefaultParameters(node, params);
    addTypeWithParams(type, params);
    sb.write("/>\n");
  }

  /// Closes current node type.
  void closeNode() {
    String tag = popTag();
    addCurrentIndent();
    sb.write("</");
    addTypeWithParams(tag);
    sb.write(">\n");
  }

  void addTypeWithParams(String type, [Map? params]) {
    if (params == null) params = new Map();
    sb.write("${type}");
    params.forEach((k, v) {
      String value;
      if (v != null) {
        String str = valueToString(v);
        value = str
            .replaceAll("<", "&lt;")
            .replaceAll(">", "&gt;")
            .replaceAll('"', "'");
      } else {
        value = "[null]";
      }
      sb.write(' $k="$value"');
    });
  }

  void addCurrentIndent() {
    sb.write(indentation);
  }

  /// Converts a parameter value into a string.
  String valueToString(var value) => value;
}
