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

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 = 0]) {}
  garply({int y = 0}) {}
  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] as MethodMirror;
  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] as MethodMirror;
  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] as MethodMirror;
  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] as MethodMirror;
  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] as MethodMirror;
  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] as MethodMirror;
  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] as MethodMirror;
  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] as MethodMirror;
  expect('Method(s(x) in s(B), getter)', xGetter);
  expect('[]', xGetter.parameters);

  MethodMirror xSetter = cm.declarations[const Symbol('x=')] as MethodMirror;
  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] as MethodMirror;
  expect('Method(s(grault) in s(B))', grault);
  expect(
      '[Parameter(s(x) in s(grault), optional, value = Instance(value = 0),'
      ' type = Class(s(int) in s(dart.core), top-level))]',
      grault.parameters);
  expect('Instance(value = 0)', grault.parameters[0].defaultValue);

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

  MethodMirror waldo = cm.declarations[#waldo] as MethodMirror;
  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] as MethodMirror;
  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(Null),'
      ' upperBound = Class(s(int) in s(dart.core), top-level)))]',
      fooInC.parameters);

  MethodMirror barInC = cm.declarations[#bar] as MethodMirror;
  expect('Method(s(bar) in s(C))', barInC);
  expect(
      '[Parameter(s(a) in s(bar),'
      ' type = TypeVariable(s(S) in s(Null),'
      ' upperBound = Class(s(int) in s(dart.core), top-level))), '
      'Parameter(s(b) in s(bar),'
      ' type = TypeVariable(s(T) in s(Null),'
      ' 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);
}
