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

// Patch library for dart:mirrors.

import 'dart:_js_helper' show patch;
import 'dart:_js_mirrors' as js;
import 'dart:_runtime' as dart;

@patch
class MirrorSystem {
  @patch
  LibraryMirror findLibrary(Symbol libraryName) {
    return libraries.values
        .singleWhere((library) => library.simpleName == libraryName);
  }

  @patch
  static String getName(Symbol symbol) => js.getName(symbol);

  @patch
  static Symbol getSymbol(String name, [LibraryMirror library]) {
    return js.getSymbol(name, library);
  }
}

@patch
MirrorSystem currentMirrorSystem() => js.currentJsMirrorSystem;

@patch
InstanceMirror reflect(dynamic reflectee) => js.reflect(reflectee);

@patch
ClassMirror reflectClass(Type key) {
  if (key is! Type || key == dynamic) {
    throw ArgumentError('$key does not denote a class');
  }
  TypeMirror tm = reflectType(key);
  if (tm is! ClassMirror) {
    throw ArgumentError("$key does not denote a class");
  }
  return (tm as ClassMirror).originalDeclaration;
}

@patch
TypeMirror reflectType(Type type, [List<Type> typeArguments = const <Type>[]]) {
  if (typeArguments != null) {
    type = _instantiateClass(type, typeArguments);
  }
  return js.reflectType(type);
}

/// Instantiates the generic class [type] with [typeArguments] and returns the
/// result.
///
/// [type] may be instantiated with type arguments already. In that case, they
/// are ignored. For example calling this function with `(List<int>, [String])`
/// and `(List<dynamic>, [String])` will produce `List<String>` in both cases.
Type _instantiateClass(Type type, List<Type> typeArguments) {
  var unwrapped = dart.unwrapType(type);
  var genericClass = dart.getGenericClass(unwrapped);
  if (genericClass == null) {
    throw ArgumentError('Type `$type` must be generic to apply '
        'type arguments: `$typeArguments`.');
  }

  var typeArgsLenth = typeArguments.length;
  var unwrappedArgs = List.filled(typeArgsLenth, null);
  for (int i = 0; i < typeArgsLenth; i++) {
    unwrappedArgs[i] = dart.unwrapType(typeArguments[i]);
  }
  var typeFormals = dart.getGenericTypeFormals(genericClass);
  if (typeFormals.length != typeArgsLenth) {
    throw ArgumentError('Type `$type` has ${typeFormals.length} type '
        'parameters, but $typeArgsLenth type arguments were '
        'passed: `$typeArguments`.');
  }
  // TODO(jmesserly): this does not validate bounds, as we don't have them
  // available at runtime. Consider storing them when dart:mirrors is enabled.
  return dart.wrapType(dart.instantiateClass(genericClass, unwrappedArgs));
}
