// 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

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) {
  if (result) _lastMatch = '$guardVariable: $label';
  return result;
}

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