// 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:unittest/unittest.dart";

main() {
  const ms5 = const Duration(milliseconds: 5);
  const twoSecs = const Duration(seconds: 2);

  test("stream timeout", () {
    StreamController c = new StreamController();
    Stream tos = c.stream.timeout(ms5);
    expect(tos.isBroadcast, false);
    tos.handleError(expectAsync((e, s) {
      expect(e, new isInstanceOf<TimeoutException>());
      expect(s, null);
    })).listen((v){ fail("Unexpected event"); });
  });

  test("stream timeout add events", () {
    StreamController c = new StreamController();
    Stream tos = c.stream.timeout(ms5, onTimeout: (sink) {
      sink.add(42);
      sink.addError("ERROR");
      sink.close();
    });
    expect(tos.isBroadcast, false);
    tos.listen(expectAsync((v) { expect(v, 42); }),
               onError: expectAsync((e, s) { expect(e, "ERROR"); }),
               onDone: expectAsync((){}));
  });

  test("stream no timeout", () {
    StreamController c = new StreamController();
    Stream tos = c.stream.timeout(twoSecs);
    int ctr = 0;
    tos.listen((v) {
                 expect(v, 42);
                 ctr++;
               },
               onError: (e, s) { fail("No error expected"); },
               onDone: expectAsync(() {
                 expect(ctr, 2);
               }));
    expect(tos.isBroadcast, false);
    c..add(42)..add(42)..close();  // Faster than a timeout!
  });

  test("stream timeout after events", () {
    StreamController c = new StreamController();
    Stream tos = c.stream.timeout(twoSecs);
    expect(tos.isBroadcast, false);
    int ctr = 0;
    tos.listen((v) {
                 expect(v, 42);
                 ctr++;
               },
               onError: expectAsync((e, s) {
                 expect(ctr, 2);
                 expect(e, new isInstanceOf<TimeoutException>());
               }));
    c..add(42)..add(42);  // No close, timeout after two events.
  });

  test("broadcast stream timeout",  () {
    StreamController c = new StreamController.broadcast();
    Stream tos = c.stream.timeout(ms5);
    expect(tos.isBroadcast, false);
    tos.handleError(expectAsync((e, s) {
      expect(e, new isInstanceOf<TimeoutException>());
      expect(s, null);
    })).listen((v){ fail("Unexpected event"); });
  });

  test("asBroadcast stream timeout",  () {
    StreamController c = new StreamController.broadcast();
    Stream tos = c.stream.asBroadcastStream().timeout(ms5);
    expect(tos.isBroadcast, false);
    tos.handleError(expectAsync((e, s) {
      expect(e, new isInstanceOf<TimeoutException>());
      expect(s, null);
    })).listen((v){ fail("Unexpected event"); });
  });

  test("mapped stream timeout",  () {
    StreamController c = new StreamController();
    Stream tos = c.stream.map((x) => 2 * x).timeout(ms5);
    expect(tos.isBroadcast, false);
    tos.handleError(expectAsync((e, s) {
      expect(e, new isInstanceOf<TimeoutException>());
      expect(s, null);
    })).listen((v){ fail("Unexpected event"); });
  });

  test("events prevent timeout", () {
    Stopwatch sw = new Stopwatch();
    StreamController c = new StreamController();
    Stream tos = c.stream.timeout(twoSecs, onTimeout: (_) {
      int elapsed = sw.elapsedMilliseconds;
      if (elapsed > 250) {
        // This should not happen, but it does occasionally.
        // Starving the periodic timer has made the test useless.
        print("Periodic timer of 5 ms delayed $elapsed ms.");
        return;
      }
      fail("Timeout not prevented by events");
      throw "ERROR";
    });
    // Start the periodic timer before we start listening to the stream.
    // This should reduce the flakiness of the test.
    int ctr = 200;  // send this many events at 5ms intervals. Then close.
    new Timer.periodic(ms5, (timer) {
      sw.reset();
      c.add(42);
      if (--ctr == 0) {
        timer.cancel();
        c.close();
      }
    });
    sw.start();

    tos.listen((v) { expect(v, 42);}, onDone: expectAsync((){}));
  });

  test("errors prevent timeout", () {
    Stopwatch sw = new Stopwatch();
    StreamController c = new StreamController();
    Stream tos = c.stream.timeout(twoSecs, onTimeout: (_) {
      int elapsed = sw.elapsedMilliseconds;
      if (elapsed > 250) {
        // This should not happen, but it does occasionally.
        // Starving the periodic timer has made the test useless.
        print("Periodic timer of 5 ms delayed $elapsed ms.");
        return;
      }
      fail("Timeout not prevented by errors");
    });

    // Start the periodic timer before we start listening to the stream.
    // This should reduce the flakiness of the test.
    int ctr = 200;  // send this many error events at 5ms intervals. Then close.
    new Timer.periodic(ms5, (timer) {
      sw.reset();
      c.addError("ERROR");
      if (--ctr == 0) {
        timer.cancel();
        c.close();
      }
    });
    sw.start();

    tos.listen((_) {},
      onError: (e, s) {
        expect(e, "ERROR");
      },
      onDone: expectAsync((){}));
  });

  test("closing prevents timeout", () {
    StreamController c = new StreamController();
    Stream tos = c.stream.timeout(twoSecs, onTimeout: (_) {
      fail("Timeout not prevented by close");
    });
    tos.listen((_) {}, onDone: expectAsync((){}));
    c.close();
  });

  test("pausing prevents timeout", () {
    StreamController c = new StreamController();
    Stream tos = c.stream.timeout(ms5, onTimeout: (_) {
      fail("Timeout not prevented by close");
    });
    var subscription = tos.listen((_) {}, onDone: expectAsync((){}));
    subscription.pause();
    new Timer(twoSecs, () {
      c.close();
      subscription.resume();
    });
  });
}
