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

class _InvocationMirror implements InvocationMirror {
  // Constants describing the invocation type.
  // _FIELD cannot be generated by regular invocation mirrors.
  static const int _METHOD = 0;
  static const int _GETTER = 1;
  static const int _SETTER = 2;
  static const int _FIELD = 3;
  static const int _TYPE_SHIFT = 0;
  static const int _TYPE_BITS = 2;
  static const int _TYPE_MASK = (1 << _TYPE_BITS) - 1;

  // These values, except _DYNAMIC, are only used when throwing
  // NoSuchMethodError for compile-time resolution failures.
  static const int _DYNAMIC = 0;
  static const int _STATIC = 1;
  static const int _CONSTRUCTOR = 2;
  static const int _TOP_LEVEL = 3;
  static const int _CALL_SHIFT = _TYPE_BITS;
  static const int _CALL_BITS = 2;
  static const int _CALL_MASK = (1 << _CALL_BITS) - 1;

  // Internal representation of the invocation mirror.
  final String _functionName;
  final List _argumentsDescriptor;
  final List _arguments;

  // External representation of the invocation mirror; populated on demand.
  String _memberName;
  int _type;
  List _positionalArguments;
  Map<String, dynamic> _namedArguments;

  void _setMemberNameAndType() {
    if (_functionName.startsWith("get:")) {
      _type = _GETTER;
      _memberName = _functionName.substring(4);
    } else if (_functionName.startsWith("set:")) {
      _type = _SETTER;
      _memberName = _functionName.substring(4) + "=";
    } else {
      _type = _METHOD;
      _memberName = _functionName;
    }
  }

  String get memberName {
    if (_memberName == null) {
      _setMemberNameAndType();
    }
    return _memberName;
  }

  List get positionalArguments {
    if (_positionalArguments == null) {
      int numPositionalArguments = _argumentsDescriptor[1];
      // Exclude receiver.
      _positionalArguments = _arguments.sublist(1, numPositionalArguments);
    }
    return _positionalArguments;
  }

  Map<String, dynamic> get namedArguments {
    if (_namedArguments == null) {
      _namedArguments = new Map<String, dynamic>();
      int numArguments = _argumentsDescriptor[0] - 1;  // Exclude receiver.
      int numPositionalArguments = _argumentsDescriptor[1] - 1;
      int numNamedArguments = numArguments - numPositionalArguments;
      for (int i = 0; i < numNamedArguments; i++) {
        String arg_name = _argumentsDescriptor[2 + 2*i];
        var arg_value = _arguments[_argumentsDescriptor[3 + 2*i]];
        _namedArguments[arg_name] = arg_value;
      }
    }
    return _namedArguments;
  }

  bool get isMethod {
    if (_type == null) {
      _setMemberNameAndType();
    }
    return _type == _METHOD;
  }

  bool get isAccessor {
    if (_type == null) {
      _setMemberNameAndType();
    }
    return _type != _METHOD;
  }

  bool get isGetter {
    if (_type == null) {
      _setMemberNameAndType();
    }
    return _type == _GETTER;
  }

  bool get isSetter {
    if (_type == null) {
      _setMemberNameAndType();
    }
    return _type == _SETTER;
  }

  _InvocationMirror(this._functionName,
                    this._argumentsDescriptor,
                    this._arguments);

  static _allocateInvocationMirror(String functionName,
                                   List argumentsDescriptor,
                                   List arguments) {
    return new _InvocationMirror(functionName, argumentsDescriptor, arguments);
  }

  static _invoke(Object receiver,
                 String functionName,
                 List argumentsDescriptor,
                 List arguments)
      native "InvocationMirror_invoke";

  invokeOn(Object receiver) {
    return _invoke(receiver, _functionName, _argumentsDescriptor, _arguments);
  }
}

