// 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/conversion_helpers.h"

#include "nb/memory_scope.h"
#include "third_party/mozjs-45/js/src/jsapi.h"
#include "third_party/mozjs-45/js/src/vm/DateObject.h"

namespace cobalt {
namespace script {
namespace mozjs {

// JSValue -> std::string
void FromJSValue(JSContext* context, JS::HandleValue value,
                 int conversion_flags, ExceptionState* exception_state,
                 std::string* out_string) {
  TRACK_MEMORY_SCOPE("Javascript");
  DCHECK_EQ(conversion_flags & ~kConversionFlagsString, 0)
      << "Unexpected conversion flags found: ";

  if (value.isNull() &&
      conversion_flags & kConversionFlagTreatNullAsEmptyString) {
    *out_string = "";
    return;
  }

  if (value.isUndefined() &&
      conversion_flags & kConversionFlagTreatUndefinedAsEmptyString) {
    *out_string = "";
    return;
  }

  JS::RootedString string(context, JS::ToString(context, value));

  if (!string) {
    exception_state->SetSimpleException(kConvertToStringFailed);
    return;
  }

  JSAutoByteString auto_byte_string;
  char* utf8_chars = auto_byte_string.encodeUtf8(context, string);
  // Utf8 encoded string is already linear, ensureFlat might make
  // JSDpendentString independent. But the overhead is not much and the only
  // API we are given requires flat string.
  JSFlatString* flat_string = string->ensureFlat(context);

  if (!utf8_chars || !flat_string) {
    exception_state->SetSimpleException(kConvertToUTF8Failed);
    return;
  }

  out_string->assign(utf8_chars, JS::GetDeflatedUTF8StringLength(flat_string));
}

// base::Time -> JSValue
void ToJSValue(JSContext* context, const base::Time& time,
               JS::MutableHandleValue out_value) {
  TRACK_MEMORY_SCOPE("Javascript");

  JS::ClippedTime clipped_time = time.is_null() ? JS::ClippedTime::invalid()
                                                : JS::TimeClip(time.ToJsTime());
  JS::RootedObject object(context, JS::NewDateObject(context, clipped_time));
  out_value.setObject(*object);
}

// JSValue -> base::Time
void FromJSValue(JSContext* context, JS::HandleValue value,
                 int conversion_flags, ExceptionState* exception_state,
                 base::Time* out_time) {
  TRACK_MEMORY_SCOPE("Javascript");

  if (!value.isObject()) {
    exception_state->SetSimpleException(kNotObjectType);
    return;
  }
  bool is_date = false;
  JS::RootedObject object(context, &value.toObject());
  JS_ObjectIsDate(context, object, &is_date);
  if (!is_date) {
    exception_state->SetSimpleException(kNotDateType);
    return;
  }
  bool is_valid = false;
  js::DateIsValid(context, object, &is_valid);
  if (!is_valid) {
    *out_time = base::Time();
    return;
  }
  // This number is milliseconds since 1970.
  double result = value.toObject().as<js::DateObject>().UTCTime().toNumber();
  *out_time =
      base::Time::FromDoubleT(result / base::Time::kMillisecondsPerSecond);
}

// ValueHandle -> JSValue
void ToJSValue(JSContext* context, const ValueHandleHolder* value_handle_holder,
               JS::MutableHandleValue out_value) {
  TRACK_MEMORY_SCOPE("Javascript");
  JS::RootedValue js_value(context);
  if (value_handle_holder) {
    // Downcast to MozjsValueHandleHolder so we can get the JS object.
    const MozjsValueHandleHolder* mozjs_value_handle_holder =
        base::polymorphic_downcast<const MozjsValueHandleHolder*>(
            value_handle_holder);
    js_value = mozjs_value_handle_holder->js_value();
  }

  out_value.set(js_value);
}

// JSValue -> ValueHandle
void FromJSValue(JSContext* context, JS::HandleValue value,
                 int conversion_flags, ExceptionState* exception_state,
                 MozjsValueHandleHolder* out_holder) {
  TRACK_MEMORY_SCOPE("Javascript");
  DCHECK_EQ(conversion_flags & ~kConversionFlagsValueHandle, 0)
      << "Unexpected conversion flags found.";

  // If |value| is expected to be an IDL object, then we are supposed to throw
  // if we get something that isn't of type Object or null.  Otherwise, we can
  // just accept anything.
  if (conversion_flags & kConversionFlagObjectOnly) {
    // https://www.w3.org/TR/WebIDL/#es-object
    // 1. If Type(V) is not Object, throw a TypeError
    // If the condition listed above is true, then the exception that we throw
    // differs depending on whether the non-object is null or not.  Thus, we
    // perform this check in two separate steps below.
    if (!value.isObjectOrNull()) {
      exception_state->SetSimpleException(kNotObjectType);
      return;
    }
    if (value.isNull()) {
      // Set an exception if this is not nullable.
      if (!(conversion_flags & kConversionFlagNullable)) {
        exception_state->SetSimpleException(kNotNullableType);
      }
      // Return here even for the non-exception case.
      return;
    }

    DCHECK(value.isObject());
    *out_holder = MozjsValueHandleHolder(context, value);
  } else {
    *out_holder = MozjsValueHandleHolder(context, value);
  }
}

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