// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/script/mozjs-45/mozjs_exception_state.h"

#include <string>
#include <vector>

#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "cobalt/script/mozjs-45/conversion_helpers.h"
#include "third_party/mozjs-45/js/src/jsexn.h"

namespace cobalt {
namespace script {
namespace mozjs {

namespace {

JSExnType ConvertToMozjsExceptionType(SimpleExceptionType type) {
  switch (type) {
    case kError:
      return JSEXN_ERR;
    case kTypeError:
      return JSEXN_TYPEERR;
    case kRangeError:
      return JSEXN_RANGEERR;
    case kReferenceError:
      return JSEXN_REFERENCEERR;
    case kSyntaxError:
      return JSEXN_SYNTAXERR;
    case kURIError:
      return JSEXN_URIERR;
  }
  NOTREACHED();
  return JSEXN_ERR;
}

const JSErrorFormatString* GetErrorMessage(void* user_ref,
                                           const unsigned error_number) {
  return static_cast<JSErrorFormatString*>(user_ref);
}

}  // namespace

void MozjsExceptionState::SetException(
    const scoped_refptr<ScriptException>& exception) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(!is_exception_set_);

  MozjsGlobalEnvironment* global_environment =
      static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context_));

  JS::RootedObject exception_object(
      context_,
      global_environment->wrapper_factory()->GetWrapperProxy(exception));
  JS::RootedValue exception_value(context_);
  exception_value.setObject(*exception_object);

  JS_SetPendingException(context_, exception_value);

  is_exception_set_ = true;
}

void MozjsExceptionState::SetSimpleExceptionVA(SimpleExceptionType type,
                                               const char* format,
                                               va_list arguments) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(!is_exception_set_);

  std::string error_message = base::StringPrintV(format, arguments);
  JSErrorFormatString format_string;
  format_string.format = error_message.c_str();
  // Already fed arguments for format.
  format_string.argCount = 0;
  format_string.exnType = ConvertToMozjsExceptionType(type);

  // This function creates a JSErrorReport, populate it with an error message
  // obtained from the given JSErrorCallback. The resulting error message is
  // passed to the context's JSErrorReporter callback.
  JS_ReportErrorNumber(context_, GetErrorMessage,
                       static_cast<void*>(&format_string), type);
  is_exception_set_ = true;
}

// static
JSObject* MozjsExceptionState::CreateErrorObject(JSContext* context,
                                                 SimpleExceptionType type) {
  JSExnType mozjs_type = ConvertToMozjsExceptionType(type);
  JS::RootedObject error_prototype(context);
  if (!JS_GetClassPrototype(context, js::GetExceptionProtoKey(mozjs_type),
                            &error_prototype)) {
    DLOG(ERROR) << "Failed to get Error prototype.";
    return NULL;
  }
  return JS_NewObjectWithGivenProto(context, NULL, error_prototype);
}

}  // namespace mozjs
}  // namespace script
}  // namespace cobalt
