// Copyright (c) 2016, 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.
library kernel.type_substitute_bounds_test;

import 'package:kernel/kernel.dart';
import 'package:kernel/type_algebra.dart';
import 'package:test/test.dart';
import 'type_parser.dart';

final List<TestCase> testCases = <TestCase>[
  testCase('T', {'T': bound('_', 'String')}, 'String'),
  testCase('List<T>', {'T': bound('_', 'String')}, 'List<String>'),
  testCase('List<List<T>>', {'T': bound('_', 'String')}, 'List<List<String>>'),
  testCase('(T) => T', {'T': bound('_', 'String')}, '(_) => String'),
  testCase('<G>(G,T) => T', {'T': bound('_', 'String')}, '<G>(G,_) => String'),
  testCase(
      '<G>(G,x:T) => T', {'T': bound('_', 'String')}, '<G>(G,x:_) => String'),
  testCase('<G:T>(G) => G', {'T': bound('_', 'String')}, '<G:_>(G) => G'),
  testCase('<G:T>(G) => G', {'T': bound('int', 'num')}, '<G:int>(G) => G'),
  testCase('<G>(T,G) => void', {'T': bound('_', 'String')}, '<G>(_,G) => void'),
  testCase('(T) => void', {'T': bound('_', 'String')}, '(_) => void'),
  testCase('(int) => T', {'T': bound('_', 'String')}, '(int) => String'),
  testCase('(int) => int', {'T': bound('_', 'String')}, '(int) => int'),
  testCase('((T) => int) => int', {'T': bound('_', 'String')},
      '((String) => int) => int'),
  testCase('<E>(<F>(T) => int) => int', {'T': bound('_', 'String')},
      '<E>(<F>(String) => int) => int'),
  testCase('(<F>(T) => int) => int', {'T': bound('_', 'String')},
      '(<F>(String) => int) => int'),
  testCase('<E>((T) => int) => int', {'T': bound('_', 'String')},
      '<E>((String) => int) => int'),
  testCase('(T?) =>* String', {'T': bound('int', 'int')}, '(int?) =>* String'),
];

class TestCase {
  final String type;
  final Map<String, TypeBound> bounds;
  final String expected;

  TestCase(this.type, this.bounds, this.expected);

  String toString() {
    var substitution = bounds.keys.map((key) {
      var bound = bounds[key];
      return '${bound.lower} <: $key <: ${bound.upper}';
    }).join(',');
    return '$type [$substitution] <: $expected';
  }
}

class TypeBound {
  final String lower, upper;

  TypeBound(this.lower, this.upper);
}

TypeBound bound(String lower, String upper) => new TypeBound(lower, upper);

TestCase testCase(String type, Map<String, TypeBound> bounds, String expected) {
  return new TestCase(type, bounds, expected);
}

main() {
  for (var testCase in testCases) {
    test('$testCase', () {
      var environment = new LazyTypeEnvironment();
      var type = environment.parse(testCase.type);
      var upperBounds = <TypeParameter, DartType>{};
      var lowerBounds = <TypeParameter, DartType>{};
      testCase.bounds.forEach((String name, TypeBound bounds) {
        var parameter = environment.getTypeParameter(name);
        upperBounds[parameter] = environment.parse(bounds.upper);
        lowerBounds[parameter] = environment.parse(bounds.lower);
      });
      var substituted =
          Substitution.fromUpperAndLowerBounds(upperBounds, lowerBounds)
              .substituteType(type);
      var expected = environment.parse(testCase.expected);
      if (substituted != expected) {
        fail('Expected `$expected` but got `$substituted`');
      }
    });
  }
}
