/// Support code for the tests in this directory.
library support;

import 'dart:io';
import 'dart:collection';
import 'package:path/path.dart' as path;
import 'package:html/src/treebuilder.dart';
import 'package:html/dom.dart';
import 'package:html/dom_parsing.dart';

typedef TreeBuilder TreeBuilderFactory(bool namespaceHTMLElements);

Map<String, TreeBuilderFactory> _treeTypes;
Map<String, TreeBuilderFactory> get treeTypes {
  if (_treeTypes == null) {
    // TODO(jmesserly): add DOM here once it's implemented
    _treeTypes = {"simpletree": (useNs) => new TreeBuilder(useNs)};
  }
  return _treeTypes;
}

final testDataDir = Platform.script.resolve('data').toFilePath();

Iterable<String> getDataFiles(String subdirectory) {
  var dir = new Directory(path.join(testDataDir, subdirectory));
  return dir.listSync().where((f) => f is File).map((f) => f.path);
}

// TODO(jmesserly): make this class simpler. We could probably split on
// "\n#" instead of newline and remove a lot of code.
class TestData extends IterableBase<Map> {
  final String _text;
  final String newTestHeading;

  TestData(String filename, [this.newTestHeading = "data"])
      // Note: can't use readAsLinesSync here because it splits on \r
      : _text = new File(filename).readAsStringSync();

  // Note: in Python this was a generator, but since we can't do that in Dart,
  // it's easier to convert it into an upfront computation.
  Iterator<Map> get iterator => _getData().iterator;

  List<Map> _getData() {
    var data = <String, String>{};
    var key = null;
    var result = <Map>[];
    var lines = _text.split('\n');
    // Remove trailing newline to match Python
    if (lines.last == '') {
      lines.removeLast();
    }
    for (var line in lines) {
      var heading = sectionHeading(line);
      if (heading != null) {
        if (data.length > 0 && heading == newTestHeading) {
          // Remove trailing newline
          data[key] = data[key].substring(0, data[key].length - 1);
          result.add(normaliseOutput(data));
          data = <String, String>{};
        }
        key = heading;
        data[key] = "";
      } else if (key != null) {
        data[key] = '${data[key]}$line\n';
      }
    }

    if (data.length > 0) {
      result.add(normaliseOutput(data));
    }
    return result;
  }

  /// If the current heading is a test section heading return the heading,
  /// otherwise return null.
  static String sectionHeading(String line) {
    return line.startsWith("#") ? line.substring(1).trim() : null;
  }

  static Map normaliseOutput(Map data) {
    // Remove trailing newlines
    data.forEach((key, value) {
      if (value.endsWith("\n")) {
        data[key] = value.substring(0, value.length - 1);
      }
    });
    return data;
  }
}

/// Serialize the [document] into the html5 test data format.
testSerializer(document) {
  return (new TestSerializer()..visit(document)).toString();
}

/// Serializes the DOM into test format. See [testSerializer].
class TestSerializer extends TreeVisitor {
  final StringBuffer _str;
  int _indent = 0;
  String _spaces = '';

  TestSerializer() : _str = new StringBuffer();

  String toString() => _str.toString();

  int get indent => _indent;

  set indent(int value) {
    if (_indent == value) return;

    var arr = new List<int>(value);
    for (int i = 0; i < value; i++) {
      arr[i] = 32;
    }
    _spaces = new String.fromCharCodes(arr);
    _indent = value;
  }

  void _newline() {
    if (_str.length > 0) _str.write('\n');
    _str.write('|$_spaces');
  }

  visitNodeFallback(Node node) {
    _newline();
    _str.write(node);
    visitChildren(node);
  }

  visitChildren(Node node) {
    indent += 2;
    for (var child in node.nodes) visit(child);
    indent -= 2;
  }

  visitDocument(node) => _visitDocumentOrFragment(node);

  _visitDocumentOrFragment(node) {
    indent += 1;
    for (var child in node.nodes) visit(child);
    indent -= 1;
  }

  visitDocumentFragment(DocumentFragment node) =>
      _visitDocumentOrFragment(node);

  visitElement(Element node) {
    _newline();
    _str.write(node);
    if (node.attributes.length > 0) {
      indent += 2;
      var keys = new List.from(node.attributes.keys);
      keys.sort((x, y) => x.compareTo(y));
      for (var key in keys) {
        var v = node.attributes[key];
        if (key is AttributeName) {
          AttributeName attr = key;
          key = "${attr.prefix} ${attr.name}";
        }
        _newline();
        _str.write('$key="$v"');
      }
      indent -= 2;
    }
    visitChildren(node);
  }
}
