// 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 Invocation {
  // 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.
  Symbol _memberName;
  int _type;
  List _positionalArguments;
  Map<Symbol, dynamic> _namedArguments;

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

  Symbol 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<Symbol, dynamic> get namedArguments {
    if (_namedArguments == null) {
      _namedArguments = new Map<Symbol, 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[new _collection_dev.Symbol.unvalidated(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);
  }

  // TODO(ahe): This is a hack.  See _LocalInstanceMirrorImpl.delegate
  // in mirrors_impl.dart
  static final _invokeOnClosure = (x, y) => y._invokeOn(x);
}
