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

// part of "core_patch.dart";

@patch
class Error {
  @patch
  static String _objectToString(Object object) {
    return Object._toString(object);
  }

  @patch
  static String _stringToSafeString(String string) {
    return json.encode(string);
  }

  @patch
  StackTrace get stackTrace => _stackTrace;

  StackTrace _stackTrace;
}

class _AssertionError extends Error implements AssertionError {
  _AssertionError._create(
      this._failedAssertion, this._url, this._line, this._column, this.message);

  // AssertionError_throwNew in errors.cc fishes the assertion source code
  // out of the script. It expects a Dart stack frame from class
  // _AssertionError. Thus we need a Dart stub that calls the native code.
  static _throwNew(int assertionStart, int assertionEnd, Object message) {
    _doThrowNew(assertionStart, assertionEnd, message);
  }

  static _doThrowNew(int assertionStart, int assertionEnd, Object message)
      native "AssertionError_throwNew";

  static _evaluateAssertion(condition) {
    if (identical(condition, true) || identical(condition, false)) {
      return condition;
    }
    if (condition is _Closure) {
      return condition.call();
    }
    if (condition is Function) {
      condition = condition();
    }
    return condition;
  }

  String get _messageString {
    if (message == null) return "is not true.";
    if (message is String) return message;
    return Error.safeToString(message);
  }

  String toString() {
    if (_url == null) {
      if (message == null) return _failedAssertion?.trim();
      return "'${_failedAssertion?.trim()}': $_messageString";
    }
    var columnInfo = "";
    if (_column > 0) {
      // Only add column information if it is valid.
      columnInfo = " pos $_column";
    }
    return "'$_url': Failed assertion: line $_line$columnInfo: "
        "'$_failedAssertion': $_messageString";
  }

  final String _failedAssertion;
  final String _url;
  final int _line;
  final int _column;
  final Object message;
}

class _TypeError extends _AssertionError implements TypeError {
  _TypeError._create(String url, int line, int column, String errorMsg)
      : super._create("is assignable", url, line, column, errorMsg);

  static _throwNew(int location, Object src_value, _Type dst_type,
      String dst_name, String bound_error_msg) native "TypeError_throwNew";

  static _throwNewIfNotLoaded(
      _LibraryPrefix prefix,
      int location,
      Object src_value,
      _Type dst_type,
      String dst_name,
      String bound_error_msg) {
    if (!prefix.isLoaded()) {
      _throwNew(location, src_value, dst_type, dst_name, bound_error_msg);
    }
  }

  String toString() => super.message;
}

class _CastError extends Error implements CastError {
  _CastError._create(this._url, this._line, this._column, this._errorMsg);

  // A CastError is allocated by TypeError._throwNew() when dst_name equals
  // Symbols::InTypeCast().

  String toString() => _errorMsg;

  // Fields _url, _line, and _column are only used for debugging purposes.
  final String _url;
  final int _line;
  final int _column;
  final String _errorMsg;
}

@patch
class FallThroughError {
  @patch
  FallThroughError._create(String url, int line)
      : _url = url,
        _line = line;

  static _throwNew(int case_clause_pos) native "FallThroughError_throwNew";

  @patch
  String toString() {
    return "'$_url': Switch case fall-through at line $_line.";
  }

  // These new fields cannot be declared final, because a constructor exists
  // in the original version of this patched class.
  String _url;
  int _line;
}

class _InternalError {
  const _InternalError(this._msg);
  String toString() => "InternalError: '${_msg}'";
  final String _msg;
}

@patch
class UnsupportedError {
  static _throwNew(String msg) {
    throw new UnsupportedError(msg);
  }
}

@patch
class CyclicInitializationError {
  static _throwNew(String variableName) {
    throw new CyclicInitializationError(variableName);
  }
}

@patch
class AbstractClassInstantiationError {
  AbstractClassInstantiationError._create(
      this._className, this._url, this._line);

  static _throwNew(int case_clause_pos, String className)
      native "AbstractClassInstantiationError_throwNew";

  @patch
  String toString() {
    return "Cannot instantiate abstract class $_className: "
        "_url '$_url' line $_line";
  }

  // These new fields cannot be declared final, because a constructor exists
  // in the original version of this patched class.
  String _url;
  int _line;
}

@patch
class NoSuchMethodError {
  // Deprecated members to be removed.
  final Object _receiver;
  final Symbol _memberName;
  final List _arguments;
  final Map<Symbol, dynamic> _namedArguments;
  final List _existingArgumentNames;

  // TODO(regis): Move _receiver declaration here:
  // final Object _receiver;
  final _InvocationMirror _invocation;

  @patch
  NoSuchMethodError.withInvocation(Object receiver, Invocation invocation)
      : _receiver = receiver,
        _invocation = invocation as _InvocationMirror;

  static void _throwNewInvocation(Object receiver, Invocation invocation) {
    throw new NoSuchMethodError.withInvocation(receiver, invocation);
  }

  // The compiler emits a call to _throwNew when it cannot resolve a static
  // method at compile time. The receiver is actually the literal class of the
  // unresolved method.
  static void _throwNew(Object receiver, String memberName, int invocation_type,
      Object typeArguments, List arguments, List argumentNames) {
    throw new NoSuchMethodError._withType(receiver, memberName, invocation_type,
        typeArguments, arguments, argumentNames);
  }

  static void _throwNewIfNotLoaded(
      _LibraryPrefix prefix,
      Object receiver,
      String memberName,
      int invocation_type,
      Object typeArguments,
      List arguments,
      List argumentNames) {
    if (!prefix.isLoaded()) {
      _throwNew(receiver, memberName, invocation_type, typeArguments, arguments,
          argumentNames);
    }
  }

  // TODO(regis): Deprecated member still used by dart2js to be removed.
  // Remember the type from the invocation mirror or static compilation
  // analysis when thrown directly with _throwNew. A negative value means
  // that no information is available.
  final int _invocation_type;

  // TODO(regis): Deprecated constructor still used by dart2js to be removed.
  @patch
  NoSuchMethodError(Object receiver, Symbol memberName,
      List positionalArguments, Map<Symbol, dynamic> namedArguments,
      [List existingArgumentNames = null])
      : _receiver = receiver,
        _memberName = memberName,
        _arguments = positionalArguments,
        _namedArguments = namedArguments,
        _existingArgumentNames = existingArgumentNames,
        _invocation_type = -1;

  // Helper to build a map of named arguments.
  static Map<Symbol, dynamic> _NamedArgumentsMap(
      List arguments, List argumentNames) {
    Map<Symbol, dynamic> namedArguments = new Map<Symbol, dynamic>();
    int numPositionalArguments = arguments.length - argumentNames.length;
    for (int i = 0; i < argumentNames.length; i++) {
      var arg_value = arguments[numPositionalArguments + i];
      namedArguments[new Symbol(argumentNames[i])] = arg_value;
    }
    return namedArguments;
  }

  // Constructor called from Exceptions::ThrowByType(kNoSuchMethod) and from
  // _throwNew above, taking a TypeArguments object rather than an unpacked list
  // of types, as well as a list of all arguments and a list of names, rather
  // than a separate list of positional arguments and a map of named arguments.
  NoSuchMethodError._withType(
      this._receiver,
      String memberName,
      int invocation_type,
      Object typeArguments,
      List arguments,
      List argumentNames)
      : this._invocation = new _InvocationMirror._withType(
            new Symbol(memberName),
            invocation_type,
            typeArguments != null
                // TODO(33073): Use actual count of type arguments in place of 0.
                ? _InvocationMirror._unpackTypeArguments(typeArguments, 0)
                : null,
            argumentNames != null
                ? arguments.sublist(0, arguments.length - argumentNames.length)
                : arguments,
            argumentNames != null
                ? _NamedArgumentsMap(arguments, argumentNames)
                : null);

  static String _existingMethodSignature(Object receiver, String methodName,
      int invocationType) native "NoSuchMethodError_existingMethodSignature";

  @patch
  String toString() {
    // TODO(regis): Remove this null check once dart2js is updated.
    if (_invocation == null) {
      // Use deprecated version of toString.
      return _toStringDeprecated();
    }
    String memberName =
        internal.Symbol.computeUnmangledName(_invocation.memberName);
    var level = (_invocation._type >> _InvocationMirror._LEVEL_SHIFT) &
        _InvocationMirror._LEVEL_MASK;
    var kind = _invocation._type & _InvocationMirror._KIND_MASK;
    if (kind == _InvocationMirror._LOCAL_VAR) {
      return "NoSuchMethodError: Cannot assign to final variable '$memberName'";
    }

    StringBuffer typeArgumentsBuf = null;
    var typeArguments = _invocation.typeArguments;
    if ((typeArguments != null) && (typeArguments.length > 0)) {
      typeArgumentsBuf = new StringBuffer();
      typeArgumentsBuf.write("<");
      for (int i = 0; i < typeArguments.length; i++) {
        if (i > 0) {
          typeArgumentsBuf.write(", ");
        }
        typeArgumentsBuf.write(Error.safeToString(typeArguments[i]));
      }
      typeArgumentsBuf.write(">");
    }
    StringBuffer argumentsBuf = new StringBuffer();
    var positionalArguments = _invocation.positionalArguments;
    int argumentCount = 0;
    if (positionalArguments != null) {
      for (; argumentCount < positionalArguments.length; argumentCount++) {
        if (argumentCount > 0) {
          argumentsBuf.write(", ");
        }
        argumentsBuf
            .write(Error.safeToString(positionalArguments[argumentCount]));
      }
    }
    var namedArguments = _invocation.namedArguments;
    if (namedArguments != null) {
      namedArguments.forEach((Symbol key, var value) {
        if (argumentCount > 0) {
          argumentsBuf.write(", ");
        }
        argumentsBuf.write(internal.Symbol.computeUnmangledName(key));
        argumentsBuf.write(": ");
        argumentsBuf.write(Error.safeToString(value));
        argumentCount++;
      });
    }
    String existingSig =
        _existingMethodSignature(_receiver, memberName, _invocation._type);
    String argsMsg = existingSig != null ? " with matching arguments" : "";

    String kindBuf;
    if (kind >= 0 && kind < 5) {
      kindBuf = (const [
        "method",
        "getter",
        "setter",
        "getter or setter",
        "variable"
      ])[kind];
    }

    StringBuffer msgBuf = new StringBuffer("NoSuchMethodError: ");
    bool is_type_call = false;
    switch (level) {
      case _InvocationMirror._DYNAMIC:
        {
          if (_receiver == null) {
            if (existingSig != null) {
              msgBuf.writeln("The null object does not have a $kindBuf "
                  "'$memberName'$argsMsg.");
            } else {
              msgBuf.writeln("The $kindBuf '$memberName' was called on null.");
            }
          } else {
            if (_receiver is _Closure) {
              msgBuf.writeln("Closure call with mismatched arguments: "
                  "function '$memberName'");
            } else if (_receiver is _Type && memberName == "call") {
              is_type_call = true;
              String name = _receiver.toString();
              msgBuf.writeln("Attempted to use type '$name' as a function. "
                  "Since types do not define a method 'call', this is not "
                  "possible. Did you intend to call the $name constructor and "
                  "forget the 'new' operator?");
            } else {
              msgBuf.writeln("Class '${_receiver.runtimeType}' has no instance "
                  "$kindBuf '$memberName'$argsMsg.");
            }
          }
          break;
        }
      case _InvocationMirror._SUPER:
        {
          msgBuf.writeln("Super class of class '${_receiver.runtimeType}' has "
              "no instance $kindBuf '$memberName'$argsMsg.");
          memberName = "super.$memberName";
          break;
        }
      case _InvocationMirror._STATIC:
        {
          msgBuf.writeln("No static $kindBuf '$memberName'$argsMsg "
              "declared in class '$_receiver'.");
          break;
        }
      case _InvocationMirror._CONSTRUCTOR:
        {
          msgBuf.writeln("No constructor '$memberName'$argsMsg declared "
              "in class '$_receiver'.");
          memberName = "new $memberName";
          break;
        }
      case _InvocationMirror._TOP_LEVEL:
        {
          msgBuf.writeln("No top-level $kindBuf '$memberName'$argsMsg "
              "declared.");
          break;
        }
    }

    if (level == _InvocationMirror._TOP_LEVEL) {
      msgBuf.writeln("Receiver: top-level");
    } else {
      msgBuf.writeln("Receiver: ${Error.safeToString(_receiver)}");
    }

    if (kind == _InvocationMirror._METHOD) {
      String m = is_type_call ? "$_receiver" : "$memberName";
      msgBuf.write("Tried calling: $m");
      if (typeArgumentsBuf != null) {
        msgBuf.write(typeArgumentsBuf);
      }
      msgBuf.write("($argumentsBuf)");
    } else if (argumentCount == 0) {
      msgBuf.write("Tried calling: $memberName");
    } else if (kind == _InvocationMirror._SETTER) {
      msgBuf.write("Tried calling: $memberName$argumentsBuf");
    } else {
      msgBuf.write("Tried calling: $memberName = $argumentsBuf");
    }

    if (existingSig != null) {
      msgBuf.write("\nFound: $memberName$existingSig");
    }

    return msgBuf.toString();
  }

  // TODO(regis): Remove this function once dart2js is updated.
  String _toStringDeprecated() {
    var level = (_invocation_type >> _InvocationMirror._LEVEL_SHIFT) &
        _InvocationMirror._LEVEL_MASK;
    var type = _invocation_type & _InvocationMirror._KIND_MASK;
    String memberName = (_memberName == null)
        ? ""
        : internal.Symbol.computeUnmangledName(_memberName);

    if (type == _InvocationMirror._LOCAL_VAR) {
      return "NoSuchMethodError: Cannot assign to final variable '$memberName'";
    }

    StringBuffer arguments = new StringBuffer();
    int argumentCount = 0;
    if (_arguments != null) {
      for (; argumentCount < _arguments.length; argumentCount++) {
        if (argumentCount > 0) {
          arguments.write(", ");
        }
        arguments.write(Error.safeToString(_arguments[argumentCount]));
      }
    }
    if (_namedArguments != null) {
      _namedArguments.forEach((Symbol key, var value) {
        if (argumentCount > 0) {
          arguments.write(", ");
        }
        arguments.write(internal.Symbol.computeUnmangledName(key));
        arguments.write(": ");
        arguments.write(Error.safeToString(value));
        argumentCount++;
      });
    }
    bool args_mismatch = _existingArgumentNames != null;
    String args_message = args_mismatch ? " with matching arguments" : "";

    String type_str;
    if (type >= 0 && type < 5) {
      type_str = (const [
        "method",
        "getter",
        "setter",
        "getter or setter",
        "variable"
      ])[type];
    }

    StringBuffer msg_buf = new StringBuffer("NoSuchMethodError: ");
    bool is_type_call = false;
    switch (level) {
      case _InvocationMirror._DYNAMIC:
        {
          if (_receiver == null) {
            if (args_mismatch) {
              msg_buf.writeln("The null object does not have a $type_str "
                  "'$memberName'$args_message.");
            } else {
              msg_buf
                  .writeln("The $type_str '$memberName' was called on null.");
            }
          } else {
            if (_receiver is _Closure) {
              msg_buf.writeln("Closure call with mismatched arguments: "
                  "function '$memberName'");
            } else if (_receiver is _Type && memberName == "call") {
              is_type_call = true;
              String name = _receiver.toString();
              msg_buf.writeln("Attempted to use type '$name' as a function. "
                  "Since types do not define a method 'call', this is not "
                  "possible. Did you intend to call the $name constructor and "
                  "forget the 'new' operator?");
            } else {
              msg_buf
                  .writeln("Class '${_receiver.runtimeType}' has no instance "
                      "$type_str '$memberName'$args_message.");
            }
          }
          break;
        }
      case _InvocationMirror._SUPER:
        {
          msg_buf.writeln("Super class of class '${_receiver.runtimeType}' has "
              "no instance $type_str '$memberName'$args_message.");
          memberName = "super.$memberName";
          break;
        }
      case _InvocationMirror._STATIC:
        {
          msg_buf.writeln("No static $type_str '$memberName'$args_message "
              "declared in class '$_receiver'.");
          break;
        }
      case _InvocationMirror._CONSTRUCTOR:
        {
          msg_buf.writeln("No constructor '$memberName'$args_message declared "
              "in class '$_receiver'.");
          memberName = "new $memberName";
          break;
        }
      case _InvocationMirror._TOP_LEVEL:
        {
          msg_buf.writeln("No top-level $type_str '$memberName'$args_message "
              "declared.");
          break;
        }
    }

    if (level == _InvocationMirror._TOP_LEVEL) {
      msg_buf.writeln("Receiver: top-level");
    } else {
      msg_buf.writeln("Receiver: ${Error.safeToString(_receiver)}");
    }

    if (type == _InvocationMirror._METHOD) {
      String m = is_type_call ? "$_receiver" : "$memberName";
      msg_buf.write("Tried calling: $m($arguments)");
    } else if (argumentCount == 0) {
      msg_buf.write("Tried calling: $memberName");
    } else if (type == _InvocationMirror._SETTER) {
      msg_buf.write("Tried calling: $memberName$arguments");
    } else {
      msg_buf.write("Tried calling: $memberName = $arguments");
    }

    if (args_mismatch) {
      StringBuffer formalParameters = new StringBuffer();
      for (int i = 0; i < _existingArgumentNames.length; i++) {
        if (i > 0) {
          formalParameters.write(", ");
        }
        formalParameters.write(_existingArgumentNames[i]);
      }
      msg_buf.write("\nFound: $memberName($formalParameters)");
    }

    return msg_buf.toString();
  }
}

class _CompileTimeError extends Error {
  final String _errorMsg;
  _CompileTimeError(this._errorMsg);
  String toString() => _errorMsg;
}

dynamic _classRangeAssert(int position, dynamic instance, _Type type, int cid,
    int lowerLimit, int upperLimit) {
  if ((cid < lowerLimit || cid > upperLimit) && instance != null) {
    _TypeError._throwNew(position, instance, type, " in type cast", null);
  }

  return instance;
}

dynamic _classIdEqualsAssert(
    int position, dynamic instance, _Type type, int cid, int otherCid) {
  if (cid != otherCid && instance != null) {
    _TypeError._throwNew(position, instance, type, " in type cast", null);
  }

  return instance;
}

/// Used by Fasta to report a runtime error when a final field with an
/// initializer is also initialized in a generative constructor.
///
/// Note: in strong mode, this is a compile-time error and this class becomes
/// obsolete.
class _DuplicatedFieldInitializerError extends Error {
  final String _name;

  _DuplicatedFieldInitializerError(this._name);

  toString() => "Error: field '$_name' is already initialized.";
}

@patch
class _ConstantExpressionError {
  @patch
  _throw(error) => throw error;
}
