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

/// Tools for manipulating HTML during code generation of analyzer and analysis
/// server.

import 'html_dom.dart' as dom;

/// Return true if the given iterable contains only whitespace text nodes.
bool containsOnlyWhitespace(Iterable<dom.Node> nodes) {
  for (var node in nodes) {
    if (!isWhitespaceNode(node)) {
      return false;
    }
  }
  return true;
}

/// Get the text contents of the element, ignoring all markup.
String innerText(dom.Element parent) {
  var buffer = StringBuffer();
  void recurse(dom.Element parent) {
    for (var child in parent.nodes) {
      if (child is dom.Text) {
        buffer.write(child.textRemoveTags);
      } else if (child is dom.Element) {
        recurse(child);
      }
    }
  }

  recurse(parent);
  return buffer.toString();
}

/// Return true if the given node is a text node containing only whitespace, or
/// a comment.
bool isWhitespaceNode(dom.Node node) {
  if (node is dom.Element) {
    return false;
  } else if (node is dom.Text) {
    return node.text.trim().isEmpty;
  }
  // Treat all other types of nodes (e.g. comments) as whitespace.
  return true;
}

/// Create an HTML element with the given name, attributes, and child nodes.
dom.Element makeElement(
    String name, Map<String, String> attributes, List<dom.Node> children) {
  var result = dom.Element.tag(name);
  result.attributes.addAll(attributes);
  for (var child in children) {
    result.append(child);
  }
  return result;
}

/// Mixin class for generating HTML.
mixin HtmlGenerator {
  List<dom.Node> _html = [];

  /// Add the given [node] to the HTML output.
  void add(dom.Node node) {
    _html.add(node);
  }

  /// Add the given [nodes] to the HTML output.
  void addAll(Iterable<dom.Node> nodes) {
    for (var node in nodes) {
      add(node);
    }
  }

  /// Execute [callback], collecting any code that is output using [write],
  /// [writeln], [add], [addAll] or [element], and return the result as a list
  /// of HTML nodes.
  List<dom.Node> collectHtml(void Function()? callback) {
    var oldHtml = _html;
    try {
      _html = <dom.Node>[];
      if (callback != null) {
        callback();
      }
      return _html;
    } finally {
      _html = oldHtml;
    }
  }

  /// Execute [callback], wrapping its output in an element with the given
  /// [name] and [attributes].
  void element(String name, Map<String, String> attributes,
      [void Function()? callback]) {
    add(makeElement(name, attributes, collectHtml(callback)));
  }

  /// Output text without ending the current line.
  void write(String text) {
    _html.add(dom.Text(text));
  }

  /// Output text, ending the current line.
  void writeln([Object obj = '']) {
    write('$obj\n');
  }
}
