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

#include "cobalt/script/mozjs-45/conversion_helpers.h"
#include "cobalt/script/mozjs-45/mozjs_exception_state.h"
#include "third_party/mozjs-45/js/src/jsiter.h"
#include "third_party/mozjs-45/js/src/vm/ProxyObject.h"

namespace cobalt {
namespace script {
namespace mozjs {

ProxyHandler::ProxyHandler(const IndexedPropertyHooks& indexed_hooks,
                           const NamedPropertyHooks& named_hooks)
    : js::DirectProxyHandler(NULL),
      indexed_property_hooks_(indexed_hooks),
      named_property_hooks_(named_hooks),
      has_custom_property_(false) {
  // If an interface supports named/indexed properties, they must have a hook to
  // check if the name/index is supported and to enumerate the properties.
  if (supports_named_properties()) {
    DCHECK(named_property_hooks_.is_supported);
    DCHECK(named_property_hooks_.enumerate_supported);
  }
  if (supports_indexed_properties()) {
    DCHECK(indexed_property_hooks_.is_supported);
    DCHECK(indexed_property_hooks_.enumerate_supported);
  }
}

/* static */
JSObject* ProxyHandler::NewProxy(JSContext* context, ProxyHandler* handler,
                                 JSObject* object, JSObject* prototype) {
  JS::RootedValue object_as_value(context, JS::ObjectOrNullValue(object));
  return js::NewProxyObject(context, handler, object_as_value, prototype);
}

bool ProxyHandler::getOwnPropertyDescriptor(
    JSContext* context, JS::HandleObject proxy, JS::HandleId id,
    JS::MutableHandle<JSPropertyDescriptor> descriptor) const {
  if (!LegacyPlatformObjectGetOwnPropertyDescriptor(context, proxy, id,
                                                    descriptor)) {
    return false;
  }
  if (descriptor.object() == NULL) {
    return js::DirectProxyHandler::getOwnPropertyDescriptor(context, proxy, id,
                                                            descriptor);
  }
  return true;
}

bool ProxyHandler::defineProperty(JSContext* cx, JS::HandleObject proxy,
                                  JS::HandleId id,
                                  js::Handle<JSPropertyDescriptor> desc,
                                  JS::ObjectOpResult& result) const {
  // This member function needs to be marked const in order to properly
  // override the js::DirectProxyHandler, however will modify its own,
  // ProxyHandler specific components, hence the need for the (ab)use of
  // const_cast.
  const_cast<ProxyHandler*>(this)->has_custom_property_ = true;
  return js::DirectProxyHandler::defineProperty(cx, proxy, id, desc, result);
}

bool ProxyHandler::ownPropertyKeys(JSContext* context, JS::HandleObject proxy,
                                   JS::AutoIdVector& properties) const {
  // https://www.w3.org/TR/WebIDL/#property-enumeration
  // Indexed properties go first, then named properties, then everything
  // else.
  JS::RootedObject object(context, js::GetProxyTargetObject(proxy));
  if (supports_indexed_properties()) {
    indexed_property_hooks_.enumerate_supported(context, object, &properties);
  }
  if (supports_named_properties()) {
    named_property_hooks_.enumerate_supported(context, object, &properties);
  }
  return js::DirectProxyHandler::ownPropertyKeys(context, proxy, properties);
}

bool ProxyHandler::delete_(JSContext* context, JS::HandleObject proxy,
                           JS::HandleId id, JS::ObjectOpResult& result) const {
  // https://www.w3.org/TR/WebIDL/#delete
  if (!JSID_IS_SYMBOL(id) &&
      (supports_named_properties() || supports_indexed_properties())) {
    // Convert the id to a JSValue, so we can easily convert it to Uint32 and
    // JSString.
    JS::RootedValue id_value(context);
    if (!JS_IdToValue(context, id, &id_value)) {
      NOTREACHED();
      return result.failCantDelete();
    }
    DCHECK(js::IsProxy(proxy));
    JS::RootedObject object(context, js::GetProxyTargetObject(proxy));
    if (supports_indexed_properties()) {
      // If the interface supports indexed properties and this is an array index
      // property name, and it is a supported property index.
      uint32_t index;
      // 1. If O supports indexed properties and P is an array index property
      // name,
      //    then:
      if (IsArrayIndexPropertyName(context, id_value, &index)) {
        if (!IsSupportedIndex(context, object, index)) {
          // 1.2. If index is not a supported property index, then return true.
          result.succeed();
        } else if (!indexed_property_hooks_.deleter) {
          // 1.3. If O does not implement an interface with an indexed property
          //    deleter, then Reject.
          result.failCantDelete();
        } else {
          bool succeeded =
              indexed_property_hooks_.deleter(context, object, index) &&
              result.succeed();
          if (succeeded) {
            result.succeed();
          } else {
            result.failCantDelete();
          }
        }
        return true;
      }
    }
    if (supports_named_properties()) {
      std::string property_name;
      MozjsExceptionState exception_state(context);
      FromJSValue(context, id_value, kNoConversionFlags, &exception_state,
                  &property_name);
      if (exception_state.is_exception_set()) {
        // The ID should be an integer or a string, so we shouldn't have any
        // exceptions converting to string.
        NOTREACHED();
        return result.failCantDelete();
      }
      if (IsNamedPropertyVisible(context, object, property_name)) {
        if (!named_property_hooks_.deleter) {
          result.failCantDelete();
        } else {
          bool succeeded =
              named_property_hooks_.deleter(context, object, property_name);
          if (succeeded) {
            result.succeed();
          } else {
            result.failCantDelete();
          }
        }
        return true;
      }
    }
  }
  return js::DirectProxyHandler::delete_(context, proxy, id, result);
}

bool ProxyHandler::LegacyPlatformObjectGetOwnPropertyDescriptor(
    JSContext* context, JS::HandleObject proxy, JS::HandleId id,
    JS::MutableHandle<JSPropertyDescriptor> descriptor) const {
  if (!JSID_IS_SYMBOL(id) &&
      (supports_named_properties() || supports_indexed_properties())) {
    // Convert the id to a JSValue, so we can easily convert it to Uint32 and
    // JSString.
    JS::RootedValue id_value(context);
    if (!JS_IdToValue(context, id, &id_value)) {
      NOTREACHED();
      return false;
    }
    JS::RootedObject object(context, js::GetProxyTargetObject(proxy));
    if (supports_indexed_properties()) {
      // If the interface supports indexed properties and this is an array index
      // property name, and it is a supported property index.
      uint32_t index;
      if (IsArrayIndexPropertyName(context, id_value, &index) &&
          IsSupportedIndex(context, object, index)) {
        descriptor.object().set(object);
        descriptor.setGetter(indexed_property_hooks_.getter);
        descriptor.setAttributes(JSPROP_SHARED | JSPROP_ENUMERATE);
        if (indexed_property_hooks_.setter) {
          descriptor.setSetter(indexed_property_hooks_.setter);
        } else {
          descriptor.get().attrs |= JSPROP_READONLY;
        }
        return true;
      }
    }
    if (supports_named_properties()) {
      std::string property_name;
      MozjsExceptionState exception_state(context);
      FromJSValue(context, id_value, kNoConversionFlags, &exception_state,
                  &property_name);
      if (exception_state.is_exception_set()) {
        // The ID should be an integer or a string, so we shouldn't have any
        // exceptions converting to string.
        NOTREACHED();
        return false;
      }
      if (IsNamedPropertyVisible(context, object, property_name)) {
        descriptor.object().set(object);
        descriptor.setAttributes(JSPROP_SHARED | JSPROP_ENUMERATE);
        descriptor.setGetter(named_property_hooks_.getter);
        if (named_property_hooks_.setter) {
          descriptor.setSetter(named_property_hooks_.setter);
        } else {
          descriptor.get().attrs |= JSPROP_READONLY;
        }
        return true;
      }
    }
  }
  return true;
}

bool ProxyHandler::IsArrayIndexPropertyName(JSContext* context,
                                            JS::HandleValue property_value,
                                            uint32_t* out_index) const {
  // https://www.w3.org/TR/WebIDL/#dfn-array-index-property-name
  // 1. Let i be ToUint32(P).
  if (property_value.isSymbol()) {
    return false;
  }
  uint32_t index;
  if (!JS::ToUint32(context, property_value, &index)) {
    return false;
  }

  // 3. If i = 2^32 - 1, then return false.
  if (index == 0xFFFFFFFF) {
    return false;
  }

  // 2. Let s be ToString(i).
  // 3. If s != P then return false.
  JS::RootedValue index_as_number_value(context, JS::NumberValue(index));
  JS::RootedString index_as_string(
      context, JS::ToString(context, index_as_number_value));
  JS::RootedValue index_as_string_value(context);
  index_as_string_value.setString(index_as_string);
  bool loosely_equal_output;
  const bool loosely_equal_success = JS_LooselyEqual(
      context, index_as_string_value, property_value, &loosely_equal_output);
  if (!loosely_equal_success || !loosely_equal_output) {
    return false;
  }

  // 4. Return true.
  *out_index = index;
  return true;
}

bool ProxyHandler::IsNamedPropertyVisible(
    JSContext* context, JS::HandleObject object,
    const std::string& property_name) const {
  // Named property visibility algorithm.
  // https://www.w3.org/TR/WebIDL/#dfn-named-property-visibility

  // 1. If P is an unforgeable property name on O, then return false.
  // 2. If O implements an interface with an [Unforgeable]-annotated attribute
  //    whose identifier is P, then return false.
  // TODO: Implement Unforgeable extended attribute.

  // 3. If P is not a supported property name of O, then return false.
  if (!IsSupportedName(context, object, property_name)) {
    return false;
  }

  // 4. If O implements an interface that has the [OverrideBuiltins] extended
  // attribute, then return true.
  // TODO: Implement OverrideBuiltins extended attribute

  // 5. If O has an own property named P, then return false.
  // 6~7. ( Walk the prototype chain and if the protoype has P, return false)

  bool found_property;
  if (!JS_HasProperty(context, object, property_name.c_str(),
                      &found_property)) {
    // An error occurred searching for the property.
    NOTREACHED();
    return true;
  }
  return !found_property;
}

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