// 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, true);
    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, true);
    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();
    });
  });
}
