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

import "dart:async";

import "package:async/async.dart";
import "package:test/test.dart";

/// Create an error with the same values as [base], except that it throwsA
/// when seeing the value [errorValue].
Stream streamError(Stream base, int errorValue, error) {
  return base.map((x) => (x == errorValue) ? throw error : x);
}

/// Make a [Stream] from an [Iterable] by adding events to a stream controller
/// at periodic intervals.
Stream mks(Iterable iterable) {
  Iterator iterator = iterable.iterator;
  StreamController controller = StreamController();
  // Some varying time between 3 and 10 ms.
  int ms = ((++ctr) * 5) % 7 + 3;
  Timer.periodic(Duration(milliseconds: ms), (Timer timer) {
    if (iterator.moveNext()) {
      controller.add(iterator.current);
    } else {
      controller.close();
      timer.cancel();
    }
  });
  return controller.stream;
}

/// Counter used to give varying delays for streams.
int ctr = 0;

main() {
  // Test that zipping [streams] gives the results iterated by [expectedData].
  testZip(Iterable<Stream> streams, Iterable expectedData) {
    List data = [];
    Stream zip = StreamZip(streams);
    zip.listen(data.add, onDone: expectAsync0(() {
      expect(data, equals(expectedData));
    }));
  }

  test("Basic", () {
    testZip([
      mks([1, 2, 3]),
      mks([4, 5, 6]),
      mks([7, 8, 9])
    ], [
      [1, 4, 7],
      [2, 5, 8],
      [3, 6, 9]
    ]);
  });

  test("Uneven length 1", () {
    testZip([
      mks([1, 2, 3, 99, 100]),
      mks([4, 5, 6]),
      mks([7, 8, 9])
    ], [
      [1, 4, 7],
      [2, 5, 8],
      [3, 6, 9]
    ]);
  });

  test("Uneven length 2", () {
    testZip([
      mks([1, 2, 3]),
      mks([4, 5, 6, 99, 100]),
      mks([7, 8, 9])
    ], [
      [1, 4, 7],
      [2, 5, 8],
      [3, 6, 9]
    ]);
  });

  test("Uneven length 3", () {
    testZip([
      mks([1, 2, 3]),
      mks([4, 5, 6]),
      mks([7, 8, 9, 99, 100])
    ], [
      [1, 4, 7],
      [2, 5, 8],
      [3, 6, 9]
    ]);
  });

  test("Uneven length 4", () {
    testZip([
      mks([1, 2, 3, 98]),
      mks([4, 5, 6]),
      mks([7, 8, 9, 99, 100])
    ], [
      [1, 4, 7],
      [2, 5, 8],
      [3, 6, 9]
    ]);
  });

  test("Empty 1", () {
    testZip([
      mks([]),
      mks([4, 5, 6]),
      mks([7, 8, 9])
    ], []);
  });

  test("Empty 2", () {
    testZip([
      mks([1, 2, 3]),
      mks([]),
      mks([7, 8, 9])
    ], []);
  });

  test("Empty 3", () {
    testZip([
      mks([1, 2, 3]),
      mks([4, 5, 6]),
      mks([])
    ], []);
  });

  test("Empty source", () {
    testZip([], []);
  });

  test("Single Source", () {
    testZip([
      mks([1, 2, 3])
    ], [
      [1],
      [2],
      [3]
    ]);
  });

  test("Other-streams", () {
    Stream st1 = mks([1, 2, 3, 4, 5, 6]).where((x) => x < 4);
    Stream st2 =
        Stream.periodic(const Duration(milliseconds: 5), (x) => x + 4).take(3);
    StreamController c = StreamController.broadcast();
    Stream st3 = c.stream;
    testZip([
      st1,
      st2,
      st3
    ], [
      [1, 4, 7],
      [2, 5, 8],
      [3, 6, 9]
    ]);
    c
      ..add(7)
      ..add(8)
      ..add(9)
      ..close();
  });

  test("Error 1", () {
    expect(
        StreamZip([
          streamError(mks([1, 2, 3]), 2, "BAD-1"),
          mks([4, 5, 6]),
          mks([7, 8, 9])
        ]).toList(),
        throwsA(equals("BAD-1")));
  });

  test("Error 2", () {
    expect(
        StreamZip([
          mks([1, 2, 3]),
          streamError(mks([4, 5, 6]), 5, "BAD-2"),
          mks([7, 8, 9])
        ]).toList(),
        throwsA(equals("BAD-2")));
  });

  test("Error 3", () {
    expect(
        StreamZip([
          mks([1, 2, 3]),
          mks([4, 5, 6]),
          streamError(mks([7, 8, 9]), 8, "BAD-3")
        ]).toList(),
        throwsA(equals("BAD-3")));
  });

  test("Error at end", () {
    expect(
        StreamZip([
          mks([1, 2, 3]),
          streamError(mks([4, 5, 6]), 6, "BAD-4"),
          mks([7, 8, 9])
        ]).toList(),
        throwsA(equals("BAD-4")));
  });

  test("Error before first end", () {
    // StreamControllers' streams with no "close" called will never be done,
    // so the fourth event of the first stream is guaranteed to come first.
    expect(
        StreamZip([
          streamError(mks([1, 2, 3, 4]), 4, "BAD-5"),
          (StreamController()..add(4)..add(5)..add(6)).stream,
          (StreamController()..add(7)..add(8)..add(9)).stream
        ]).toList(),
        throwsA(equals("BAD-5")));
  });

  test("Error after first end", () {
    StreamController controller = StreamController();
    controller..add(7)..add(8)..add(9);
    // Transformer that puts error into controller when one of the first two
    // streams have sent a done event.
    StreamTransformer trans =
        StreamTransformer.fromHandlers(handleDone: (EventSink s) {
      Timer.run(() {
        controller.addError("BAD-6");
      });
      s.close();
    });
    testZip([
      mks([1, 2, 3]).transform(trans),
      mks([4, 5, 6]).transform(trans),
      controller.stream
    ], [
      [1, 4, 7],
      [2, 5, 8],
      [3, 6, 9]
    ]);
  });

  test("Pause/Resume", () {
    int sc1p = 0;
    StreamController c1 = StreamController(onPause: () {
      sc1p++;
    }, onResume: () {
      sc1p--;
    });

    int sc2p = 0;
    StreamController c2 = StreamController(onPause: () {
      sc2p++;
    }, onResume: () {
      sc2p--;
    });

    var done = expectAsync0(() {
      expect(sc1p, equals(1));
      expect(sc2p, equals(0));
    }); // Call to complete test.

    Stream zip = StreamZip([c1.stream, c2.stream]);

    const ms25 = Duration(milliseconds: 25);

    // StreamIterator uses pause and resume to control flow.
    StreamIterator it = StreamIterator(zip);

    it.moveNext().then((hasMore) {
      expect(hasMore, isTrue);
      expect(it.current, equals([1, 2]));
      return it.moveNext();
    }).then((hasMore) {
      expect(hasMore, isTrue);
      expect(it.current, equals([3, 4]));
      c2.add(6);
      return it.moveNext();
    }).then((hasMore) {
      expect(hasMore, isTrue);
      expect(it.current, equals([5, 6]));
      Future.delayed(ms25).then((_) {
        c2.add(8);
      });
      return it.moveNext();
    }).then((hasMore) {
      expect(hasMore, isTrue);
      expect(it.current, equals([7, 8]));
      c2.add(9);
      return it.moveNext();
    }).then((hasMore) {
      expect(hasMore, isFalse);
      done();
    });

    c1
      ..add(1)
      ..add(3)
      ..add(5)
      ..add(7)
      ..close();
    c2..add(2)..add(4);
  });

  test("pause-resume2", () {
    var s1 = Stream.fromIterable([0, 2, 4, 6, 8]);
    var s2 = Stream.fromIterable([1, 3, 5, 7]);
    var sz = StreamZip([s1, s2]);
    int ctr = 0;
    StreamSubscription sub;
    sub = sz.listen(expectAsync1((v) {
      expect(v, equals([ctr * 2, ctr * 2 + 1]));
      if (ctr == 1) {
        sub.pause(Future.delayed(const Duration(milliseconds: 25)));
      } else if (ctr == 2) {
        sub.pause();
        Future.delayed(const Duration(milliseconds: 25)).then((_) {
          sub.resume();
        });
      }
      ctr++;
    }, count: 4));
  });
}
