// Copyright 2016 Google Inc. 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 (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 (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).
  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 visiblity 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 prootype 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
