// Copyright (c) 2015, 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 dart._runtime;

// We need to set these properties while the sdk is only partially initialized
// so we cannot use regular Dart fields.
// The default values for these properties are set when the global_ final field
// in runtime.dart is initialized.

// Override, e.g., for testing
void trapRuntimeErrors(bool flag) {
  JS('', 'dart.__trapRuntimeErrors = #', flag);
}

void ignoreWhitelistedErrors(bool flag) {
  JS('', 'dart.__ignoreWhitelistedErrors = #', flag);
}

// TODO(jmesserly): remove this?
void ignoreAllErrors(bool flag) {
  JS('', 'dart.__ignoreAllErrors = #', flag);
}

argumentError(value) {
  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
  throw new ArgumentError.value(value);
}

throwUnimplementedError(String message) {
  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
  throw new UnimplementedError(message);
}

assertFailed(message) {
  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
  throw new AssertionErrorImpl(message);
}

throwCyclicInitializationError([Object field]) {
  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
  throw new CyclicInitializationError(field);
}

throwNullValueError() {
  // TODO(vsm): Per spec, we should throw an NSM here.  Technically, we ought
  // to thread through method info, but that uglifies the code and can't
  // actually be queried ... it only affects how the error is printed.
  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
  throw new NoSuchMethodError(
      null, new Symbol('<Unexpected Null Value>'), null, null, null);
}

castError(obj, expectedType, [@notNull bool isImplicit = false]) {
  var actualType = getReifiedType(obj);
  var message = _castErrorMessage(actualType, expectedType);
  if (JS('!', 'dart.__ignoreAllErrors')) {
    JS('', 'console.error(#)', message);
    return obj;
  }
  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
  var error =
      isImplicit ? new TypeErrorImpl(message) : new CastErrorImpl(message);
  throw error;
}

String _castErrorMessage(from, to) {
  // If both types are generic classes, see if we can infer generic type
  // arguments for `from` that would allow the subtype relation to work.
  var fromClass = getGenericClass(from);
  if (fromClass != null) {
    var fromTypeFormals = getGenericTypeFormals(fromClass);
    var fromType = instantiateClass(fromClass, fromTypeFormals);
    var inferrer = new _TypeInferrer(fromTypeFormals);
    if (inferrer.trySubtypeMatch(fromType, to)) {
      var inferredTypes = inferrer.getInferredTypes();
      if (inferredTypes != null) {
        var inferred = instantiateClass(fromClass, inferredTypes);
        return "Type '${typeName(from)}' should be '${typeName(inferred)}' "
            "to implement expected type '${typeName(to)}'.";
      }
    }
  }
  return "Type '${typeName(from)}' is not a subtype of "
      "expected type '${typeName(to)}'.";
}
