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

// SharedOptions=--enable-experiment=patterns,records

import "package:expect/expect.dart";

main() {
  Expect.equals('0: int', differentFinalityNotUsedInBody(0, 0));
  Expect.equals('1: final int', differentFinalityNotUsedInBody(1, 1));
  Expect.equals('2: var', differentFinalityNotUsedInBody(2, 2));
  Expect.equals('3: final', differentFinalityNotUsedInBody(3, 3));

  Expect.equals('0: int', differentTypeNotUsedInBody(0, 0));
  Expect.equals('true: bool', differentTypeNotUsedInBody(1, true));
  Expect.equals('s: var', differentTypeNotUsedInBody(2, 's'));

  Expect.equals('unique: unique', differentVariableNotUsedInBody(0, 'unique'));
  Expect.equals('inTwo: in', differentVariableNotUsedInBody(1, 'in'));
  Expect.equals('inTwo: two', differentVariableNotUsedInBody(2, 'two'));

  Expect.equals('one: var', sharedAnnotatedAndUnannotated(0, 'one'));
  Expect.equals('two: Object', sharedAnnotatedAndUnannotated(1, 'two'));

  Expect.equals('one: var', sharedAnnotatedAndPromotionInferred(0, 'one'));
  Expect.equals('two: int', sharedAnnotatedAndPromotionInferred(1, 'two'));

  Expect.equals('0: 0: list', sharedDifferentContext([0, true]));
  Expect.equals('1: 1: map', sharedDifferentContext({'a': 1, 'b': true}));
  Expect.equals('2: 2: record', sharedDifferentContext((a: 2, b: true)));
  Expect.equals('3: 3: nested', sharedDifferentContext((a: 3, b: [true])));
}

/// OK if variables in different cases have different finality if not used in
/// the body.
Object? differentFinalityNotUsedInBody(int caseKey, Object value) {
  switch ((caseKey, value)) {
    case (0, int x) when _guard(x, 'int'):
    case (1, final int x) when _guard(x, 'final int'):
    case (2, var x) when _guard(x, 'var'):
    case (3, final x) when _guard(x, 'final'):
      return _matchedCase();
    default:
      Expect.fail('Should not reach this.');
  }
}

/// OK if variables in different cases have different types if not used in the
/// body.
Object? differentTypeNotUsedInBody(int caseKey, Object value) {
  switch ((caseKey, value)) {
    case (0, int x) when _guard(x, 'int'):
    case (1, bool x) when _guard(x, 'bool'):
    case (2, var x) when _guard(x, 'var'): // Infer Object.
      return _matchedCase();
    default:
      Expect.fail('Should not reach this.');
  }
}

/// OK if some variables only exist in some cases if they aren't used in the
/// body.
Object? differentVariableNotUsedInBody(int caseKey, Object value) {
  switch ((value, value)) {
    case (0, var unique) when _guard(unique, 'unique'):
    case (1, var inTwo) when _guard(inTwo, 'inTwo'):
    case (2, var inTwo) when _guard(inTwo, 'inTwo'):
      return _matchedCase();
    default:
      Expect.fail('Should not reach this.');
  }
}

/// Variables can be shared if not all are annotated as long as the inferred
/// type matches.
Object? sharedAnnotatedAndUnannotated(int caseKey, Object value) {
  switch ((caseKey, value)) {
    case (0, var a) when _guard(a, 'var'):
    case (1, Object a) when _guard(a, 'Object'):
      // Use pattern variable in body:
      Expect.equals(value, a);
      return _matchedCase();
    default:
      Expect.fail('Should not reach this.');
  }
}

/// Variables can be shared if not all are annotated as long as the type
/// inferred using promotion matches.
Object? sharedAnnotatedAndPromotionInferred(int caseKey, Object value) {
  // Promote value to int.
  if (value is int) {
    switch ((caseKey, value)) {
      case (0, var a) when _guard(a, 'var'):
      case (1, int a) when _guard(a, 'int'):
        // Use pattern variable in body:
        Expect.equals(value, a);
        return _matchedCase();
      default:
        Expect.fail('Should not reach this.');
    }
  }
}

/// Variables can be shared even when they occur in different contexts in their
/// respective patterns.
Object? sharedDifferentContext(Object value) {
  // OK, since inferred type is same as annotated.
  switch (value) {
    case [int a, bool b] when _guard(a, 'list'):
    case {'b': bool b, 'a': int a} when _guard(a, 'map'):
    case (a: int a, b: bool b) when _guard(a, 'record'):
    case (a: int a, b: [bool b]) when _guard(a, 'nested'):
      // Use pattern variables in body:
      return '$a: ${_matchedCase()}';
    default:
      Expect.fail('Should not reach this.');
  }
}

String _lastMatch = 'none';

bool _guard(Object guardVariable, String label) {
  _lastMatch = '$guardVariable: $label';
  return true;
}

String _matchedCase() {
  var result = _lastMatch;
  _lastMatch = 'none';
  return result;
}
