@TestOn('vm')
library parser_test;

import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as pathos;
import 'package:test/test.dart';
import 'package:html/dom.dart';
import 'package:html/parser.dart';
import 'package:html/parser_console.dart' as parser_console;
import 'package:html/src/inputstream.dart' as inputstream;
import 'support.dart';

// Run the parse error checks
// TODO(jmesserly): presumably we want this on by default?
final checkParseErrors = false;

String namespaceHtml(String expected) {
  // TODO(jmesserly): this is a workaround for http://dartbug.com/2979
  // We can't do regex replace directly =\
  // final namespaceExpected = new RegExp(@"^(\s*)<(\S+)>", multiLine: true);
  // return expected.replaceAll(namespaceExpected, @"$1<html $2>");
  final namespaceExpected = new RegExp(r"^(\|\s*)<(\S+)>");
  var lines = expected.split("\n");
  for (int i = 0; i < lines.length; i++) {
    var match = namespaceExpected.firstMatch(lines[i]);
    if (match != null) {
      lines[i] = "${match[1]}<html ${match[2]}>";
    }
  }
  return lines.join("\n");
}

void runParserTest(
    String groupName,
    String innerHTML,
    String input,
    String expected,
    List errors,
    TreeBuilderFactory treeCtor,
    bool namespaceHTMLElements) {
  // XXX - move this out into the setup function
  // concatenate all consecutive character tokens into a single token
  var builder = treeCtor(namespaceHTMLElements);
  var parser = new HtmlParser(input, tree: builder);

  Node document;
  if (innerHTML != null) {
    document = parser.parseFragment(innerHTML);
  } else {
    document = parser.parse();
  }

  var output = testSerializer(document);

  if (namespaceHTMLElements) {
    expected = namespaceHtml(expected);
  }

  expect(output, equals(expected),
      reason:
          "\n\nInput:\n$input\n\nExpected:\n$expected\n\nReceived:\n$output");

  if (checkParseErrors) {
    expect(parser.errors.length, equals(errors.length),
        reason: "\n\nInput:\n$input\n\nExpected errors (${errors.length}):\n"
            "${errors.join('\n')}\n\n"
            "Actual errors (${parser.errors.length}):\n"
            "${parser.errors.map((e) => '$e').join('\n')}");
  }
}

void main() {
  test('dart:io', () {
    // ensure IO support is unregistered
    expect(inputstream.consoleSupport,
        new isInstanceOf<inputstream.ConsoleSupport>());
    var file = new File('$testDataDir/parser_feature/raw_file.html').openSync();
    expect(() => parse(file), throwsA(new isInstanceOf<ArgumentError>()));
    parser_console.useConsole();
    expect(parse(file).body.innerHtml.trim(), 'Hello world!');
  });

  for (var path in getDataFiles('tree-construction')) {
    if (!path.endsWith('.dat')) continue;

    var tests = new TestData(path, "data");
    var testName = pathos.basenameWithoutExtension(path);

    group(testName, () {
      for (var testData in tests) {
        var input = testData['data'];
        var errors = testData['errors'];
        var innerHTML = testData['document-fragment'];
        var expected = testData['document'];
        if (errors != null) {
          errors = errors.split("\n");
        }

        for (var treeCtor in treeTypes.values) {
          for (var namespaceHTMLElements in const [false, true]) {
            test(_nameFor(input), () {
              runParserTest(testName, innerHTML, input, expected, errors,
                  treeCtor, namespaceHTMLElements);
            });
          }
        }
      }
    });
  }
}

/// Extract the name for the test based on the test input data.
_nameFor(String input) {
  // Using jsonDecode to unescape other unicode characters
  var escapeQuote = input
      .replaceAll(new RegExp('\\\\.'), '_')
      .replaceAll(new RegExp('\u0000'), '_')
      .replaceAll('"', '\\"')
      .replaceAll(new RegExp('[\n\r\t]'), '_');
  return jsonDecode('"$escapeQuote"');
}
