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

// Tests the functionality proposed in
// https://github.com/dart-lang/language/issues/1618#issuecomment-1507241494,
// using if-null expressions.

import '../static_type_helper.dart';

/// Ensures a context type of `_` for the operand, if no type argument is
/// supplied.
Object? contextUnknown<T>(T x) => x;

/// Ensures a context type of `Iterable<T>` for the operand, or `Iterable<_>` if
/// no type argument is supplied.
Object? contextIterable<T>(Iterable<T> x) => x;

class A {}

class B1<T> implements A {}

class B2<T> implements A {}

class C1<T> implements B1<T>, B2<T> {}

class C2<T> implements B1<T>, B2<T> {}

/// Ensures a context type of `B1<T>` for the operand, or `B1<_>` if no type
/// argument is supplied.
Object? contextB1<T>(B1<T> x) => x;

main() {
  // - An if-null expression `e` of the form `e1 ?? e2` with context type K is
  //   analyzed as follows:
  //
  //   - Let T1 be the type of `e1` inferred with context type K?.
  {
    // Check the context type of `e1`:
    // - Where the context is established using a function call argument.
    context<num?>((contextType(1)..expectStaticType<Exactly<num?>>()) ?? 2);
    context<num>((contextType(1)..expectStaticType<Exactly<num?>>()) ?? 2);

    // - Where the context is established using local variable promotion.
    Object? o;
    o = 0 as Object?;
    if (o is num?) {
      o = (contextType(1)..expectStaticType<Exactly<num?>>()) ?? 2;
    }
    o = 0 as Object?;
    if (o is num) {
      o = (contextType(1)..expectStaticType<Exactly<num?>>()) ?? 2;
    }
  }

  //   - Let T2 be the type of `e2` inferred with context type J, where:
  //     - If K is `_`, J = T1.
  {
    // Check the context type of `e2`.
    var string = '';
    var stringQuestion = null as String?;
    contextUnknown(
        // ignore: dead_null_aware_expression
        string ?? (contextType('')..expectStaticType<Exactly<String>>()));
    contextUnknown(stringQuestion ??
        (contextType('')..expectStaticType<Exactly<String?>>()));
  }

  //     - Otherwise, J = K.
  {
    var intQuestion = null as int?;
    context<num?>(
        intQuestion ?? (contextType(2)..expectStaticType<Exactly<num?>>()));
    context<num>(
        intQuestion ?? (contextType(2)..expectStaticType<Exactly<num>>()));
  }

  //   - Let T be UP(NonNull(T1), T2).
  //   - Let S be the greatest closure of K.
  //   - If T <: S, then the type of `e` is T.
  //     (Testing this case here. Otherwise continued below.)
  {
    // This example has:
    // - K = Object
    // - T1 = int?
    // - T2 = double
    // Which implies:
    // - T = num
    // - S = Object
    // We have:
    // - T <: S
    // Therefore the type of `e` is T = num.
    var intQuestion = null as int?;
    var d = 2.0;
    context<Object>((intQuestion ?? d)..expectStaticType<Exactly<num>>());

    // This example has:
    // - K = Iterable<_>
    // - T1 = Iterable<int>?
    // - T2 = Iterable<double>
    // Which implies:
    // - T = Iterable<num>
    // - S = Iterable<Object?>
    // We have:
    // - T <: S
    // Therefore the type of `e` is T = Iterable<num>.
    var iterableIntQuestion = null as Iterable<int>?;
    var iterableDouble = <double>[] as Iterable<double>;
    contextIterable((iterableIntQuestion ?? iterableDouble)
      ..expectStaticType<Exactly<Iterable<num>>>());
  }

  //   - Otherwise, if NonNull(T1) <: S and T2 <: S, then the type of `e` is S.
  {
    // This example has:
    // - K = B1<_>
    // - T1 = C1<int>?
    // - T2 = C2<double>
    // Which implies:
    // - T = A
    // - S = B1<Object?>
    // We have:
    // - T <!: S
    // - NonNull(T1) <: S
    // - T2 <: S
    // Therefore the type of `e` is S = B1<Object?>.
    var c1IntQuestion = null as C1<int>?;
    var c2Double = C2<double>();
    contextB1(
        (c1IntQuestion ?? c2Double)..expectStaticType<Exactly<B1<Object?>>>());

    // This example has:
    // - K = B1<Object>
    // - T1 = C1<int>?
    // - T2 = C2<double>
    // Which implies:
    // - T = A
    // - S = B1<Object>
    // We have:
    // - T <!: S
    // - NonNull(T1) <: S
    // - T2 <: S
    // Therefore the type of `e` is S = B1<Object>.
    contextB1<Object>(
        (c1IntQuestion ?? c2Double)..expectStaticType<Exactly<B1<Object>>>());

    // This example has:
    // - K = Iterable<num>
    // - T1 = Iterable<int>?
    // - T2 = List<num>
    // Which implies:
    // - T = Object
    // - S = Iterable<num>
    // We have:
    // - T <!: S
    // - NonNull(T1) <: S
    // - T2 <: S
    // Therefore the type of `e` is S = Iterable<num>.
    var iterableIntQuestion = null as Iterable<int>?;
    var listNum = <num>[];
    context<Iterable<num>>((iterableIntQuestion ?? listNum)
      ..expectStaticType<Exactly<Iterable<num>>>());
  }

  //   - Otherwise, the type of `e` is T.
  {
    var intQuestion = null as int?;
    var d = 2.0;
    Object? o;
    var doubleQuestion = null as double?;
    o = 0 as Object?;
    if (o is int?) {
      // This example has:
      // - K = int?
      // - T1 = int?
      // - T2 = double
      // Which implies:
      // - T = num
      // - S = int?
      // We have:
      // - T <!: S
      // - NonNull(T1) <: S
      // - T2 <!: S
      // The fact that T2 <!: S precludes using S as static type.
      // Therefore the type of `e` is T = num.
      // We avoid having a compile-time error because `o` can be demoted.
      o = (intQuestion ?? d)..expectStaticType<Exactly<num>>();
    }
    o = 0 as Object?;
    if (o is int?) {
      // This example has:
      // - K = int?
      // - T1 = double?
      // - T2 = int?
      // Which implies:
      // - T = num?
      // - S = int?
      // We have:
      // - T <!: S
      // - NonNull(T1) <!: S
      // - T2 <: S
      // The fact that NonNull(T1) <!: S precludes using S as static type.
      // Therefore the type of `e` is T = num?.
      // We avoid having a compile-time error because `o` can be demoted.
      o = (doubleQuestion ?? intQuestion)..expectStaticType<Exactly<num?>>();
    }
    o = '' as Object?;
    if (o is String?) {
      // This example has:
      // - K = String?
      // - T1 = int?
      // - T2 = double
      // Which implies:
      // - T = num
      // - S = String?
      // We have:
      // - T <!: S
      // - NonNull(T1) <!: S
      // - T2 <!: S
      // The fact that NonNull(T1) <!: S and T2 <!: S precludes using S as
      // static type.
      // Therefore the type of `e` is T = num.
      // We avoid having a compile-time error because `o` can be demoted.
      o = (intQuestion ?? d)..expectStaticType<Exactly<num>>();
    }
  }
}
