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

// @dart = 2.9

library line_splitter_test;

import "package:expect/expect.dart";
import 'dart:async';
import 'dart:convert';
import 'dart:math' as MATH;

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

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

void testManyLines() {
  int breakIndex = 0;

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

  var buffer = inputs.fold(new StringBuffer(), (buff, 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) {
  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 = MATH.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);
    }
  }
}
