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

// This tests uses the multi-test "ok" feature:
// none: Desired behaviour, passing on the VM.
// 01: Trimmed version for dart2js.
//
// TODO(rmacnak,ahe): Remove multi-test when VM and dart2js are on par.

/** Test of [ParameterMirror]. */
library test.parameter_test;

@MirrorsUsed(targets: 'test.parameter_test', override: '*')
import 'dart:mirrors';

import 'package:expect/expect.dart';
import 'stringify.dart';

class B {
  B();
  B.foo(int x);
  B.bar(int z, x);

  // TODO(6490): Currently only supported by the VM.
  B.baz(final int x, int y, final int z);
  B.qux(int x, [int y= 3 + 1]);
  B.quux(int x, {String str: "foo"});
  B.corge({int x: 3 * 17, String str: "bar"});

  var _x;
  get x =>  _x;
  set x(final value) { _x = value; }

  grault([int x]) {}
  garply({int y}) {}
  waldo(int z) {}
}

class C <S extends int, T> {
  // TODO(6490): Currently only supported by the VM.
  foo(int a, S b) => b;
  bar(S a, T b, num c) {}
}

main() {
  ClassMirror cm = reflectClass(B);
  var constructors = new Map<Symbol, MethodMirror>();
  cm.declarations.forEach((k, v) {
    if (v is MethodMirror && v.isConstructor) constructors[k] = v;
  });

  List<Symbol> constructorKeys =
      [#B, #B.bar, #B.baz, #B.foo, #B.quux, #B.qux, #B.corge];
  Expect.setEquals(constructorKeys, constructors.keys);

  MethodMirror unnamedConstructor = constructors[#B];
  expect('Method(s(B) in s(B), constructor)', unnamedConstructor);
  expect('[]', unnamedConstructor.parameters);
  expect('Class(s(B) in s(test.parameter_test), top-level)',
         unnamedConstructor.returnType);

  MethodMirror fooConstructor = constructors[#B.foo];
  expect('Method(s(B.foo) in s(B), constructor)', fooConstructor);
  expect('[Parameter(s(x) in s(B.foo),'
         ' type = Class(s(int) in s(dart.core), top-level))]',
         fooConstructor.parameters);
  expect('Class(s(B) in s(test.parameter_test), top-level)',
         fooConstructor.returnType);

  MethodMirror barConstructor = constructors[#B.bar];
  expect('Method(s(B.bar) in s(B), constructor)', barConstructor);
  expect('[Parameter(s(z) in s(B.bar),'
         ' type = Class(s(int) in s(dart.core), top-level)), '
         'Parameter(s(x) in s(B.bar),'
         ' type = Type(s(dynamic), top-level))]',
         barConstructor.parameters);
  expect('Class(s(B) in s(test.parameter_test), top-level)',
         barConstructor.returnType);

  // dart2js stops testing here.
  return;  /// 01: ok

  MethodMirror bazConstructor = constructors[#B.baz];
  expect('Method(s(B.baz) in s(B), constructor)', bazConstructor);
  expect('[Parameter(s(x) in s(B.baz), final,'
         ' type = Class(s(int) in s(dart.core), top-level)), '
         'Parameter(s(y) in s(B.baz),'
         ' type = Class(s(int) in s(dart.core), top-level)), '
         'Parameter(s(z) in s(B.baz), final,'
         ' type = Class(s(int) in s(dart.core), top-level))]',
         bazConstructor.parameters);
  expect('Class(s(B) in s(test.parameter_test), top-level)',
         bazConstructor.returnType);

  MethodMirror quxConstructor = constructors[#B.qux];
  expect('Method(s(B.qux) in s(B), constructor)', quxConstructor);
  expect('[Parameter(s(x) in s(B.qux),'
         ' type = Class(s(int) in s(dart.core), top-level)), '
         'Parameter(s(y) in s(B.qux), optional,'
         ' value = Instance(value = 4),'
         ' type = Class(s(int) in s(dart.core), top-level))]',
         quxConstructor.parameters);
  expect('Class(s(B) in s(test.parameter_test), top-level)',
         quxConstructor.returnType);

  MethodMirror quuxConstructor = constructors[#B.quux];
  expect('Method(s(B.quux) in s(B), constructor)', quuxConstructor);
  expect('[Parameter(s(x) in s(B.quux),'
         ' type = Class(s(int) in s(dart.core), top-level)), '
         'Parameter(s(str) in s(B.quux), optional, named,'
         ' value = Instance(value = foo),'
         ' type = Class(s(String) in s(dart.core), top-level))]',
         quuxConstructor.parameters);
  expect('Class(s(B) in s(test.parameter_test), top-level)',
         quuxConstructor.returnType);

  MethodMirror corgeConstructor = constructors[#B.corge];
  expect('Method(s(B.corge) in s(B), constructor)', corgeConstructor);
  expect('[Parameter(s(x) in s(B.corge), optional, named,'
         ' value = Instance(value = 51),'
         ' type = Class(s(int) in s(dart.core), top-level)), '
         'Parameter(s(str) in s(B.corge), optional, named,'
         ' value = Instance(value = bar),'
         ' type = Class(s(String) in s(dart.core), top-level))]',
         corgeConstructor.parameters);
  expect('Class(s(B) in s(test.parameter_test), top-level)',
         corgeConstructor.returnType);

  MethodMirror xGetter = cm.declarations[#x];
  expect('Method(s(x) in s(B), getter)', xGetter);
  expect('[]', xGetter.parameters);

  MethodMirror xSetter = cm.declarations[const Symbol('x=')];
  expect('Method(s(x=) in s(B), setter)', xSetter);
  expect('[Parameter(s(value) in s(x=), final,'
         ' type = Type(s(dynamic), top-level))]',
         xSetter.parameters);

  MethodMirror grault = cm.declarations[#grault];
  expect('Method(s(grault) in s(B))', grault);
  expect('[Parameter(s(x) in s(grault), optional,'
         ' type = Class(s(int) in s(dart.core), top-level))]',
         grault.parameters);
  expect('Instance(value = <null>)', grault.parameters[0].defaultValue);

  MethodMirror garply = cm.declarations[#garply];
  expect('Method(s(garply) in s(B))', garply);
  expect('[Parameter(s(y) in s(garply), optional, named,'
         ' type = Class(s(int) in s(dart.core), top-level))]',
         garply.parameters);
  expect('Instance(value = <null>)', garply.parameters[0].defaultValue);

  MethodMirror waldo = cm.declarations[#waldo];
  expect('Method(s(waldo) in s(B))', waldo);
  expect('[Parameter(s(z) in s(waldo),' 
         ' type = Class(s(int) in s(dart.core), top-level))]',
         waldo.parameters);
  expect('<null>', waldo.parameters[0].defaultValue);

  cm = reflectClass(C);

  MethodMirror fooInC = cm.declarations[#foo];
  expect('Method(s(foo) in s(C))', fooInC);
  expect('[Parameter(s(a) in s(foo),'
         ' type = Class(s(int) in s(dart.core), top-level)), '
         'Parameter(s(b) in s(foo),'
         ' type = TypeVariable(s(S) in s(C),'
         ' upperBound = Class(s(int) in s(dart.core), top-level)))]',
         fooInC.parameters);

  MethodMirror barInC = cm.declarations[#bar];
  expect('Method(s(bar) in s(C))', barInC);
  expect('[Parameter(s(a) in s(bar),'
         ' type = TypeVariable(s(S) in s(C),'
         ' upperBound = Class(s(int) in s(dart.core), top-level))), '
         'Parameter(s(b) in s(bar),'
         ' type = TypeVariable(s(T) in s(C),'
         ' upperBound = Class(s(Object) in s(dart.core), top-level))), '
         'Parameter(s(c) in s(bar),'
         ' type = Class(s(num) in s(dart.core), top-level))]',
         barInC.parameters);
}
