// Copyright (c) 2021, 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.

// test w/ `dart test -N use_build_context_synchronously`

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

extension on BuildContext {
  bool get mounted => false;
}

void mountedBinOpAnd(BuildContext context, bool condition) async {
  await Future<void>.delayed(Duration());
  if (condition && context.mounted) {
    await Navigator.of(context).pushNamed('routeName');// OK
  }
}

void mountedBinOpAOr(BuildContext context, bool condition) async {
  await Future<void>.delayed(Duration());
  if (condition || !mounted) return;
  await Navigator.of(context).pushNamed('routeName'); // OK
}

void awaitInSwitchCase(BuildContext context) async {
  await Future<void>.delayed(Duration());
  switch (1) {
    case 1:
      await Navigator.of(context).pushNamed('routeName'); // LINT
      break;
  }
}

void awaitInSwitchCase_mountedCheckBeforeSwitch(BuildContext context) async {
  await Future<void>.delayed(Duration());
  if (!mounted) return;
  switch (1) {
    case 1:
      await Navigator.of(context).pushNamed('routeName'); // OK
      break;
  }
}

bool get mounted => true;

BuildContext? get contextOrNull => null;

class ContextHolder {
  BuildContext? get contextOrNull => null;
}

void f2(BuildContext? contextOrNull) {}

void nullableContext() async {
  f2(contextOrNull);
  await Future<void>.delayed(Duration());
  f2(contextOrNull); // OK
}

void nullableContext2(ContextHolder holder) async {
  f2(holder.contextOrNull);
  await Future<void>.delayed(Duration());
  f2(holder.contextOrNull); // OK
}

void nullableContext3() async {
  f2(contextOrNull);
  await Future<void>.delayed(Duration());
  var renderObject = contextOrNull?.findRenderObject(); // OK
}

void unawaited(Future<void> future) {}

void methodWithBuildContextParameter2f(BuildContext context) async {
  try {
    await Future<void>.delayed(Duration());
    f(context); // LINT
  } on Exception {
    f(context); // TODO: LINT
  }
}

class WidgetStateContext {
  bool get mounted => false;
}

void f(BuildContext context) {}

void func(Function f) {}

class MyWidget extends StatefulWidget {
  @override
  State createState() => _MyState();
}

void directAccess(BuildContext context) async {
  await Future<void>.delayed(Duration());

  var renderObject = context.findRenderObject(); // LINT
}

Future<bool> binaryExpression(BuildContext context) async {
  bool f2(BuildContext context) => true;

  f2(context);

  await Future<void>.delayed(Duration());

  return true || f2(context); // LINT
}

class C {
  BuildContext context;
  C(this.context);
}

class _MyState extends State<MyWidget> {
  void methodUsingStateContext1() async {
    // Uses context from State.
    Navigator.of(context).pushNamed('routeName'); // OK

    await Future<void>.delayed(Duration());

    // Not ok. Used after an async gap without checking mounted.
    Navigator.of(context).pushNamed('routeName'); // LINT
  }

  void methodUsingStateContext2() async {
    // Uses context from State.
    Navigator.of(context).pushNamed('routeName'); // OK

    await Future<void>.delayed(Duration());

    if (!mounted) return;

    // OK. mounted checked first.
    Navigator.of(context).pushNamed('routeName'); // OK
  }

  void methodUsingStateContext2a() async {
    await Future<void>.delayed(Duration());
    if (!mounted) print('oops');

    // Need a return after the mounted check.
    Navigator.of(context).pushNamed('routeName'); // LINT
  }

  void methodUsingStateContext2b() async {
    await Future<void>.delayed(Duration());
    if (!mounted) {
      print('ok');
      return;
    }

    // Mounted check does return.
    Navigator.of(context).pushNamed('routeName'); //OK
  }

  void methodUsingStateContext3() async {
    f(context);

    await Future<void>.delayed(Duration());

    f(context); // LINT
  }

  void methodUsingStateContext4() async {
    void f(BuildContext context) {}

    f(context);

    await Future<void>.delayed(Duration());

    f(context); // LINT
  }

  void methodUsingStateContext5() async {
    C(context);

    await Future<void>.delayed(Duration());

    C(context); // LINT
  }

  void methodUsingStateContext6() async {
    Future<int> f() async => Future.value(10);

    print(await f());

    C(context); // LINT
  }

  // Method given a build context to use.
  void methodWithBuildContextParameter1(BuildContext context) async {
    Navigator.of(context).pushNamed('routeName'); // OK

    await Future<void>.delayed(Duration());
    Navigator.of(context).pushNamed('routeName'); // LINT
  }

  // Same as above, but using a conditional path.
  void methodWithBuildContextParameter2(BuildContext context) async {
    if (defaultTargetPlatform == TargetPlatform.iOS) {
      await Future<void>.delayed(Duration());
    }
    Navigator.of(context).pushNamed('routeName'); // LINT
  }

  // Another conditional path.
  void methodWithBuildContextParameter2a(BuildContext context) async {
    bool f() => true;
    while (f()) {
      await Future<void>.delayed(Duration());
    }
    Navigator.of(context).pushNamed('routeName'); // LINT
  }

  // And another.
  void methodWithBuildContextParameter2b(BuildContext context) async {
    for (var i = 0; i < 1; ++i) {
      await Future<void>.delayed(Duration());
    }
    Navigator.of(context).pushNamed('routeName'); // LINT
  }

  // And another.
  void methodWithBuildContextParameter2c(BuildContext context) async {
    for (var i in [1]) {
      await Future<void>.delayed(Duration());
    }
    Navigator.of(context).pushNamed('routeName'); // LINT
  }

  // And another.
  void methodWithBuildContextParameter2d(BuildContext context) async {
    bool f() => true;
    do {
      await Future<void>.delayed(Duration());
    } while (f());
    Navigator.of(context).pushNamed('routeName'); // LINT
  }

  Future<void> methodWithBuildContextParameter2e(BuildContext context) async {
    await Future<void>.delayed(Duration());
    if (!mounted) return;
    unawaited(methodWithBuildContextParameter2e(context)); //OK
  }

  void methodWithBuildContextParameter2g(BuildContext context) async {
    await Future<void>.delayed(Duration());
    switch (1) {
      case 1:
        if (!mounted) return;
        await Navigator.of(context).pushNamed('routeName'); // OK
        break;
    }
  }

  void methodWithBuildContextParameter2h(BuildContext context) async {
    try {
      await Future<void>.delayed(Duration());
    } finally {
      // ...
    }

    try {
      // ...
    } on Exception catch (e) {
      if (!mounted) return;
      f(context); // OK
      return;
    }

    if (!mounted) return;
    f(context); // OK
  }

  void methodWithBuildContextParameter2i(BuildContext context) async {
    try {
      await Future<void>.delayed(Duration());
    } finally {
      if (!mounted) return;
    }

    f(context); // OK
  }

  // Mounted checks are deliberately naive.
  void methodWithBuildContextParameter3(BuildContext context) async {
    Navigator.of(context).pushNamed('routeName'); // OK

    await Future<void>.delayed(Duration());

    if (!mounted) return;

    // Mounted doesn't cover provided context but that's by design.
    Navigator.of(context).pushNamed('routeName'); // OK
  }

  void methodWithMountedFieldCheck(
      BuildContext context, WidgetStateContext stateContext) async {
    await Future<void>.delayed(Duration());
    if (!stateContext.mounted) return;
    f(context); // OK
  }

  @override
  Widget build(BuildContext context) => Placeholder();
}

void topLevel(BuildContext context) async {
  Navigator.of(context).pushNamed('routeName'); // OK

  await Future<void>.delayed(Duration());
  Navigator.of(context).pushNamed('routeName'); // LINT
}

void topLevel2(BuildContext context) async {
  Navigator.of(context).pushNamed('routeName'); // OK

  await Future<void>.delayed(Duration());
  // todo (pq): consider other conditionals (for, while, do, ...)
  if (true) {
    Navigator.of(context).pushNamed('routeName'); // LINT
  }
}

void topLevel3(BuildContext context) async {
  while (true) {
    // OK the first time only!
    Navigator.of(context).pushNamed('routeName'); // TODO: LINT
    await Future<void>.delayed(Duration());
  }
}

void topLevel4(BuildContext context) async {
  Navigator.of(context).pushNamed('routeName');
  await Future<void>.delayed(Duration());
  if (mounted) {
    Navigator.of(context).pushNamed('routeName'); // OK
  }
}

void topLevel5(BuildContext context) async {
  Navigator.of(context).pushNamed('routeName');
  await Future<void>.delayed(Duration());

  switch ('') {
    case 'a':
      if (!mounted) {
        break;
      }
      Navigator.of(context).pushNamed('routeName2'); // OK
      break;
    default: //nothing.
  }
}

void topLevel6(BuildContext context) async {
  Navigator.of(context).pushNamed('route1'); // OK
  if (true) {
    await Future<void>.delayed(Duration());
    return;
  }
  Navigator.of(context).pushNamed('route2'); // OK
}

void topLevel7(BuildContext context) async {
  Navigator.of(context).pushNamed('route1'); // OK
  if (true) {
    await Future<void>.delayed(Duration());
    return;
  } else {
    await Future<void>.delayed(Duration());
    return;
  }
  Navigator.of(context).pushNamed('route2'); // OK
}

void topLevel8(BuildContext context) async {
  Navigator.of(context).pushNamed('route1'); // OK
  if (true) {
    await Future<void>.delayed(Duration());
  } else {
    await Future<void>.delayed(Duration());
    return;
  }
  Navigator.of(context).pushNamed('route2'); // LINT
}

void topLevel9(BuildContext context) async {
  Navigator.of(context).pushNamed('route1'); // OK
  while (true) {
    await Future<void>.delayed(Duration());
    break;
  }
  Navigator.of(context).pushNamed('route2'); // LINT
}

void closure(BuildContext context) async {
  await Future<void>.delayed(Duration());

  // todo (pq): what about closures?
  func(() {
    f(context); // TODO: LINT
  });
}
