// Copyright (c) 2014, 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 'package:expect/async_helper.dart';
import 'package:expect/expect.dart';
import 'dart:async';

main() {
  asyncStart();
  testNoChange();
  testWithReplacement();
  asyncEnd();
}

class MockStack implements StackTrace {
  final int id;
  const MockStack(this.id);
  String toString() => "MocKStack($id)";
}

const stack1 = const MockStack(1);
const stack2 = const MockStack(2);

class SomeError implements Error {
  final int id;
  const SomeError(this.id);
  StackTrace get stackTrace => stack2;
  String toString() => "SomeError($id)";
}

const error1 = const SomeError(1);
const error2 = const SomeError(2);

Null expectError(e, s) {
  // Remember one asyncStart per use of this callback.
  Expect.identical(error1, e);
  Expect.identical(stack1, s);
  asyncEnd();
  return null;
}

Null expectErrorOnly(e, s) {
  // Remember one asyncStart per use of this callback.
  Expect.identical(error1, e);
  asyncEnd();
  return null;
}

AsyncError? replace(self, parent, zone, e, s) {
  if (identical(error1, e)) {
    // Give parent chance to replace your replacements.
    return parent.errorCallback(zone, error2, stack2) ??
        AsyncError(error2, stack2);
  }
  return parent.errorCallback(zone, e, s);
}

var replaceZoneSpec = new ZoneSpecification(errorCallback: replace);

// Expectation after replacing.
Null expectReplaced(e, s) {
  Expect.identical(error2, e);
  Expect.identical(stack2, s);
  asyncEnd();
  return null;
}

void testProgrammaticErrors(expectError) {
  {
    asyncStart();
    Completer c = new Completer();
    c.future.catchError(expectError);
    c.completeError(error1, stack1);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream.listen(null, onError: expectError, cancelOnError: true);
    controller.addError(error1, stack1);
  }

  {
    asyncStart();
    StreamController controller = new StreamController(sync: true);
    controller.stream.listen(null, onError: expectError, cancelOnError: true);
    controller.addError(error1, stack1);
  }

  {
    asyncStart();
    StreamController controller = new StreamController.broadcast();
    controller.stream.listen(null, onError: expectError, cancelOnError: true);
    controller.addError(error1, stack1);
  }

  {
    asyncStart();
    StreamController controller = new StreamController.broadcast(sync: true);
    controller.stream.listen(null, onError: expectError, cancelOnError: true);
    controller.addError(error1, stack1);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream.asBroadcastStream().listen(
      null,
      onError: expectError,
      cancelOnError: true,
    );
    controller.addError(error1, stack1);
  }

  {
    asyncStart();
    StreamController controller = new StreamController(sync: true);
    controller.stream.asBroadcastStream().listen(
      null,
      onError: expectError,
      cancelOnError: true,
    );
    controller.addError(error1, stack1);
  }

  {
    asyncStart();
    Future f = new Future.error(error1, stack1);
    f.catchError(expectError);
  }
}

void testThrownErrors(expectErrorOnly) {
  // Throw error in non-registered callback.
  {
    asyncStart();
    Future f = new Future(() => throw error1);
    f.catchError(expectErrorOnly);
  }

  {
    asyncStart();
    Future f = new Future.microtask(() => throw error1);
    f.catchError(expectErrorOnly);
  }

  {
    asyncStart();
    Future f = new Future.sync(() => throw error1);
    f.catchError(expectErrorOnly);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream
        .map((x) => throw error1)
        .listen(null, onError: expectErrorOnly, cancelOnError: true);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream
        .where((x) => throw error1)
        .listen(null, onError: expectErrorOnly, cancelOnError: true);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream.forEach((x) => throw error1).catchError(expectErrorOnly);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream
        .expand((x) => throw error1)
        .listen(null, onError: expectErrorOnly, cancelOnError: true);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream
        .asyncMap((x) => throw error1)
        .listen(null, onError: expectErrorOnly, cancelOnError: true);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream
        .asyncExpand((x) => throw error1)
        .listen(null, onError: expectErrorOnly, cancelOnError: true);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream
        .handleError((e, s) => throw error1)
        .listen(null, onError: expectErrorOnly, cancelOnError: true);
    controller.addError("ignore", null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream
        .skipWhile((x) => throw error1)
        .listen(null, onError: expectErrorOnly, cancelOnError: true);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream
        .takeWhile((x) => throw error1)
        .listen(null, onError: expectErrorOnly, cancelOnError: true);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    Future<bool?>.value(
      controller.stream.every((x) => throw error1),
    ).catchError(expectErrorOnly);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    Future<bool?>.value(
      controller.stream.any((x) => throw error1),
    ).catchError(expectErrorOnly);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream
        .firstWhere((x) => throw error1)
        .catchError(expectErrorOnly);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream
        .lastWhere((x) => throw error1)
        .catchError(expectErrorOnly);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream
        .singleWhere((x) => throw error1)
        .catchError(expectErrorOnly);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream
        .reduce((x, y) => throw error1)
        .catchError(expectErrorOnly);
    controller.add(null);
    controller.add(null);
  }

  {
    asyncStart();
    StreamController controller = new StreamController();
    controller.stream
        .fold(null, (x, y) => throw error1)
        .catchError(expectErrorOnly);
    controller.add(null);
  }
}

testNoChange() {
  void testTransparent() {
    testProgrammaticErrors(expectError);
    testThrownErrors(expectErrorOnly);
  }

  // Run directly.
  testTransparent();

  // Run in a zone that doesn't change callback.
  runZoned(
    testTransparent,
    zoneSpecification: new ZoneSpecification(
      handleUncaughtError: (s, p, z, e, t) {},
    ),
  );

  // Run in zone that delegates to root zone
  runZoned(
    testTransparent,
    zoneSpecification: new ZoneSpecification(
      errorCallback: (s, p, z, e, t) => p.errorCallback(z, e, t),
    ),
  );

  // Run in a zone that returns null from the callback.
  runZoned(
    testTransparent,
    zoneSpecification: new ZoneSpecification(
      errorCallback: (s, p, z, e, t) => null,
    ),
  );

  // Run in zone that returns same values.
  runZoned(
    testTransparent,
    zoneSpecification: new ZoneSpecification(
      errorCallback: (s, p, z, e, t) => new AsyncError(e, t),
    ),
  );

  // Run in zone that returns null, inside zone that does replacement.
  runZoned(() {
    runZoned(
      testTransparent,
      zoneSpecification: new ZoneSpecification(
        errorCallback: (s, p, z, e, t) => null,
      ),
    );
  }, zoneSpecification: replaceZoneSpec);
}

void testWithReplacement() {
  void testReplaced() {
    testProgrammaticErrors(expectReplaced);
    testThrownErrors(expectReplaced);
  }

  // Zone which replaces errors.
  runZoned(testReplaced, zoneSpecification: replaceZoneSpec);

  // Nested zone, only innermost gets to act.
  runZoned(() {
    runZoned(testReplaced, zoneSpecification: replaceZoneSpec);
  }, zoneSpecification: replaceZoneSpec);

  // Use delegation to parent which replaces.
  runZoned(() {
    runZoned(
      testReplaced,
      zoneSpecification: new ZoneSpecification(
        errorCallback: (s, p, z, e, t) => p.errorCallback(z, e, t),
      ),
    );
  }, zoneSpecification: replaceZoneSpec);
}
