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

library line_splitter_test;

import 'dart:async';
import 'dart:convert';
import 'dart:math';

import "package:expect/expect.dart";

const lineTerminators = const ['\n', '\r', '\r\n'];

void main() {
  testSimpleConvert();
  testSplit();
  testSplitWithOffsets();
  testManyLines();
  testReadLine1();
  testReadLine2();
  testChunkedConversion();
  testCarry();
}

void testManyLines() {
  int breakIndex = 0;

  var inputs = const ['line1', 'line2', 'long line 3', ' line 4 ', 'l5'];

  var buffer = inputs.fold(new StringBuffer(), (dynamic buff, dynamic e) {
    buff.write(e);
    buff.write(lineTerminators[breakIndex]);

    breakIndex++;
    breakIndex = breakIndex % lineTerminators.length;

    return buff;
  });

  var foo = _getLinesSliced(buffer.toString());
  Expect.equals(inputs.join(), foo);
}

String _getLinesSliced(String str) {
  late String lines;
  var stringSink =
      new StringConversionSink.withCallback((result) => lines = result);
  var sink = new LineSplitter().startChunkedConversion(stringSink);

  const chunkSize = 3;
  var index = 0;
  while (index < str.length) {
    var end = min(str.length, index + chunkSize);

    sink.addSlice(str, index, end, false);
    index += chunkSize;
  }

  sink.close();
  return lines;
}

void testSimpleConvert() {
  var decoder = new LineSplitter();
  for (var lf in lineTerminators) {
    var test = "line1${lf}line2${lf}line3";

    var result = decoder.convert(test);

    Expect.listEquals(['line1', 'line2', 'line3'], result);
  }

  var test = "Line1\nLine2\r\nLine3\rLine4\n\n\n\r\n\r\n\r\r";
  var result = decoder.convert(test);

  Expect.listEquals(
      ['Line1', 'Line2', 'Line3', 'Line4', '', '', '', '', '', ''], result);
}

void testReadLine1() {
  var controller = new StreamController<List<int>>(sync: true);
  var stream =
      controller.stream.transform(utf8.decoder).transform(const LineSplitter());

  var stage = 0;
  var done = false;

  void stringData(line) {
    Expect.equals(stage, 0);
    Expect.equals("Line", line);
    stage++;
  }

  void streamClosed() {
    Expect.equals(1, stage);
    done = true;
  }

  stream.listen(stringData, onDone: streamClosed);

  // Note: codeUnits is fine. Text is ASCII.
  controller.add("Line".codeUnits);
  controller.close();
  Expect.isTrue(done, 'should be done by now');
}

void testReadLine2() {
  var controller = new StreamController<List<int>>(sync: true);

  var stream =
      controller.stream.transform(utf8.decoder).transform(const LineSplitter());

  var expectedLines = [
    'Line1',
    'Line2',
    'Line3',
    'Line4',
    '',
    '',
    '',
    '',
    '',
    '',
    'Line5',
    'Line6'
  ];

  var index = 0;

  stream.listen((line) {
    Expect.equals(expectedLines[index++], line);
  });

  // Note: codeUnits is fine. Text is ASCII.
  controller.add("Line1\nLine2\r\nLine3\rLi".codeUnits);
  controller.add("ne4\n".codeUnits);
  controller.add("\n\n\r\n\r\n\r\r".codeUnits);
  controller.add("Line5\r".codeUnits);
  controller.add("\nLine6\n".codeUnits);
  controller.close();
  Expect.equals(expectedLines.length, index);
}

void testSplit() {
  for (var lf in lineTerminators) {
    var test = "line1${lf}line2${lf}line3";
    var result = LineSplitter.split(test).toList();
    Expect.listEquals(['line1', 'line2', 'line3'], result);
  }

  var test = "Line1\nLine2\r\nLine3\rLine4\n\n\n\r\n\r\n\r\r";
  var result = LineSplitter.split(test).toList();

  Expect.listEquals(
      ['Line1', 'Line2', 'Line3', 'Line4', '', '', '', '', '', ''], result);
}

void testSplitWithOffsets() {
  for (var lf in lineTerminators) {
    var test = "line1${lf}line2${lf}line3";
    var i2 = 5 + lf.length; // index of "line2".
    Expect.equals(5 + lf.length, i2);

    var result = LineSplitter.split(test, 4).toList();
    Expect.listEquals(['1', 'line2', 'line3'], result);

    result = LineSplitter.split(test, 5).toList();
    Expect.listEquals(['', 'line2', 'line3'], result);

    result = LineSplitter.split(test, i2).toList();
    Expect.listEquals(['line2', 'line3'], result);

    result = LineSplitter.split(test, 0, i2 + 2).toList();
    Expect.listEquals(['line1', 'li'], result);

    result = LineSplitter.split(test, i2, i2 + 5).toList();
    Expect.listEquals(['line2'], result);
  }

  var test = "Line1\nLine2\r\nLine3\rLine4\n\n\n\r\n\r\n\r\r";

  var result = LineSplitter.split(test).toList();

  Expect.listEquals(
      ['Line1', 'Line2', 'Line3', 'Line4', '', '', '', '', '', ''], result);

  test = "a\n\nb\r\nc\n\rd\r\re\r\n\nf\r\n";
  result = LineSplitter.split(test).toList();
  Expect.listEquals(["a", "", "b", "c", "", "d", "", "e", "", "f"], result);
}

void testChunkedConversion() {
  // Test any split of this complex string.
  var test = "a\n\nb\r\nc\n\rd\r\re\r\n\nf\rg\nh\r\n";
  var result = ["a", "", "b", "c", "", "d", "", "e", "", "f", "g", "h"];
  for (int i = 0; i < test.length; i++) {
    var output = [];
    var splitter = new LineSplitter();
    var outSink = new ChunkedConversionSink<String>.withCallback(output.addAll);
    var sink = splitter.startChunkedConversion(outSink);
    sink.addSlice(test, 0, i, false);
    sink.addSlice(test, i, test.length, false);
    sink.close();
    Expect.listEquals(result, output);
  }

  // Test the string split into three parts in any way.
  for (int i = 0; i < test.length; i++) {
    for (int j = i; j < test.length; j++) {
      var output = [];
      var splitter = new LineSplitter();
      var outSink =
          new ChunkedConversionSink<String>.withCallback(output.addAll);
      var sink = splitter.startChunkedConversion(outSink);
      sink.addSlice(test, 0, i, false);
      sink.addSlice(test, i, j, false);
      sink.addSlice(test, j, test.length, true);
      Expect.listEquals(result, output);
    }
  }
}

void testCarry() {
  // Test, when multiple chunks contribute to the same line,
  // That the carry-over is combined correctly.

  // Test multiple chunks of carry, ending in linefeeds or not.
  {
    var output = [];
    var splitter = new LineSplitter();
    var outSink = new ChunkedConversionSink<String>.withCallback(output.addAll);
    var sink = splitter.startChunkedConversion(outSink);

    sink.add("abcd");
    sink.add("fghi");
    sink.add("jklm");
    sink.add("nopq\r"); // Multiple chunks in carry, ends in \r.
    sink.add("\nrstu"); // Followed by \n.
    sink.close();

    Expect.listEquals(["abcdfghijklmnopq", "rstu"], output);
  }

  {
    var output = [];
    var splitter = new LineSplitter();
    var outSink = new ChunkedConversionSink<String>.withCallback(output.addAll);
    var sink = splitter.startChunkedConversion(outSink);

    sink.add("abcd");
    sink.add("fghi");
    sink.add("jklm");
    sink.add("nopq\r"); // Multiple chunks in carry, ends in \r.
    sink.add("rstu"); // Not followed by \n.
    sink.close();

    Expect.listEquals(["abcdfghijklmnopq", "rstu"], output);
  }

  {
    var output = [];
    var splitter = new LineSplitter();
    var outSink = new ChunkedConversionSink<String>.withCallback(output.addAll);
    var sink = splitter.startChunkedConversion(outSink);

    sink.add("abcd");
    sink.add("fghi");
    sink.add("jklm");
    sink.add("nopq\r"); // Multiple chunks in carry, ends in \r.
    sink.close(); // Not followed by anything.

    Expect.listEquals(["abcdfghijklmnopq"], output);
  }

  {
    var output = [];
    var splitter = new LineSplitter();
    var outSink = new ChunkedConversionSink<String>.withCallback(output.addAll);
    var sink = splitter.startChunkedConversion(outSink);

    sink.add("abcd");
    sink.add("fghi");
    sink.add("jklm");
    sink.add("nopq"); // Multiple chunks in carry, no linebreak.
    sink.close();

    Expect.listEquals(["abcdfghijklmnopq"], output);
  }
}
