// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "array.h"

#include <Zend/zend_API.h>
#include <Zend/zend_interfaces.h>

#include <ext/spl/spl_iterators.h>

// This is not self-contained: it must be after other Zend includes.
#include <Zend/zend_exceptions.h>

#include "arena.h"
#include "convert.h"
#include "def.h"
#include "php-upb.h"
#include "protobuf.h"

static void RepeatedFieldIter_make(zval *val, zval *repeated_field);

// -----------------------------------------------------------------------------
// RepeatedField
// -----------------------------------------------------------------------------

typedef struct {
  zend_object std;
  zval arena;
  upb_array *array;
  upb_fieldtype_t type;
  const Descriptor* desc;  // When values are messages.
} RepeatedField;

zend_class_entry *RepeatedField_class_entry;
static zend_object_handlers RepeatedField_object_handlers;

// PHP Object Handlers /////////////////////////////////////////////////////////

/**
 * RepeatedField_create()
 *
 * PHP class entry function to allocate and initialize a new RepeatedField
 * object.
 */
static zend_object* RepeatedField_create(zend_class_entry *class_type) {
  RepeatedField *intern = emalloc(sizeof(RepeatedField));
  zend_object_std_init(&intern->std, class_type);
  intern->std.handlers = &RepeatedField_object_handlers;
  Arena_Init(&intern->arena);
  intern->array = NULL;
  intern->desc = NULL;
  // Skip object_properties_init(), we don't allow derived classes.
  return &intern->std;
}

/**
 * RepeatedField_dtor()
 *
 * Object handler to destroy a RepeatedField. This releases all resources
 * associated with the message. Note that it is possible to access a destroyed
 * object from PHP in rare cases.
 */
static void RepeatedField_destructor(zend_object* obj) {
  RepeatedField* intern = (RepeatedField*)obj;
  ObjCache_Delete(intern->array);
  zval_ptr_dtor(&intern->arena);
  zend_object_std_dtor(&intern->std);
}

static HashTable *RepeatedField_GetProperties(zval *object TSRMLS_DC) {
  return NULL;  // We do not have a properties table.
}

static zval *RepeatedField_GetPropertyPtrPtr(zval *object, zval *member,
                                             int type, void **cache_slot) {
  return NULL;  // We don't offer direct references to our properties.
}

// C Functions from array.h ////////////////////////////////////////////////////

// These are documented in the header file.

void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr,
                                 const upb_fielddef *f, zval *arena) {
  if (!arr) {
    ZVAL_NULL(val);
    return;
  }

  if (!ObjCache_Get(arr, val)) {
    RepeatedField *intern = emalloc(sizeof(RepeatedField));
    zend_object_std_init(&intern->std, RepeatedField_class_entry);
    intern->std.handlers = &RepeatedField_object_handlers;
    ZVAL_COPY(&intern->arena, arena);
    intern->array = arr;
    intern->type = upb_fielddef_type(f);
    intern->desc = Descriptor_GetFromFieldDef(f);
    // Skip object_properties_init(), we don't allow derived classes.
    ObjCache_Add(intern->array, &intern->std);
    ZVAL_OBJ(val, &intern->std);
  }
}

upb_array *RepeatedField_GetUpbArray(zval *val, const upb_fielddef *f,
                                     upb_arena *arena) {
  if (Z_ISREF_P(val)) {
    ZVAL_DEREF(val);
  }

  if (Z_TYPE_P(val) == IS_ARRAY) {
    // Auto-construct, eg. [1, 2, 3] -> upb_array([1, 2, 3]).
    upb_array *arr = upb_array_new(arena, upb_fielddef_type(f));
    HashTable *table = HASH_OF(val);
    HashPosition pos;
    upb_fieldtype_t type = upb_fielddef_type(f);
    const Descriptor *desc = Descriptor_GetFromFieldDef(f);

    zend_hash_internal_pointer_reset_ex(table, &pos);

    while (true) {
      zval *zv = zend_hash_get_current_data_ex(table, &pos);
      upb_msgval val;

      if (!zv) return arr;

      if (!Convert_PhpToUpbAutoWrap(zv, &val, type, desc, arena)) {
        return NULL;
      }

      upb_array_append(arr, val, arena);
      zend_hash_move_forward_ex(table, &pos);
    }
  } else if (Z_TYPE_P(val) == IS_OBJECT &&
             Z_OBJCE_P(val) == RepeatedField_class_entry) {
    // Unwrap existing RepeatedField object to get the upb_array* inside.
    RepeatedField *intern = (RepeatedField*)Z_OBJ_P(val);
    const Descriptor *desc = Descriptor_GetFromFieldDef(f);

    if (intern->type != upb_fielddef_type(f) || intern->desc != desc) {
      php_error_docref(NULL, E_USER_ERROR,
                       "Wrong type for this repeated field.");
    }

    upb_arena_fuse(arena, Arena_Get(&intern->arena));
    return intern->array;
  } else {
    php_error_docref(NULL, E_USER_ERROR, "Must be a repeated field");
    return NULL;
  }
}

// RepeatedField PHP methods ///////////////////////////////////////////////////

/**
 * RepeatedField::__construct()
 *
 * Constructs an instance of RepeatedField.
 * @param long Type of the stored element.
 * @param string Message/Enum class.
 */
PHP_METHOD(RepeatedField, __construct) {
  RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());
  upb_arena *arena = Arena_Get(&intern->arena);
  zend_long type;
  zend_class_entry* klass = NULL;

  if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|C", &type, &klass) != SUCCESS) {
    return;
  }

  intern->type = pbphp_dtype_to_type(type);
  intern->desc = Descriptor_GetFromClassEntry(klass);

  if (intern->type == UPB_TYPE_MESSAGE && klass == NULL) {
    php_error_docref(NULL, E_USER_ERROR,
                     "Message/enum type must have concrete class.");
    return;
  }

  intern->array = upb_array_new(arena, intern->type);
  ObjCache_Add(intern->array, &intern->std);
}

/**
 * RepeatedField::append()
 *
 * Append element to the end of the repeated field.
 * @param object The element to be added.
 */
PHP_METHOD(RepeatedField, append) {
  RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());
  upb_arena *arena = Arena_Get(&intern->arena);
  zval *php_val;
  upb_msgval msgval;

  if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &php_val) != SUCCESS ||
      !Convert_PhpToUpb(php_val, &msgval, intern->type, intern->desc, arena)) {
    return;
  }

  upb_array_append(intern->array, msgval, arena);
}

/**
 * RepeatedField::offsetExists()
 *
 * Implements the ArrayAccess interface. Invoked when PHP code calls:
 *
 *   isset($arr[$idx]);
 *   empty($arr[$idx]);
 *
 * @param long The index to be checked.
 * @return bool True if the element at the given index exists.
 */
PHP_METHOD(RepeatedField, offsetExists) {
  RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());
  zend_long index;

  if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
    return;
  }

  RETURN_BOOL(index >= 0 && index < upb_array_size(intern->array));
}

/**
 * RepeatedField::offsetGet()
 *
 * Implements the ArrayAccess interface. Invoked when PHP code calls:
 *
 *   $x = $arr[$idx];
 *
 * @param long The index of the element to be fetched.
 * @return object The stored element at given index.
 * @exception Invalid type for index.
 * @exception Non-existing index.
 */
PHP_METHOD(RepeatedField, offsetGet) {
  RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());
  zend_long index;
  upb_msgval msgval;
  zval ret;

  if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
    return;
  }

  if (index < 0 || index >= upb_array_size(intern->array)) {
    zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index);
    return;
  }

  msgval = upb_array_get(intern->array, index);
  Convert_UpbToPhp(msgval, &ret, intern->type, intern->desc, &intern->arena);
  RETURN_ZVAL(&ret, 0, 1);
}

/**
 * RepeatedField::offsetSet()
 *
 * Implements the ArrayAccess interface. Invoked when PHP code calls:
 *
 *   $arr[$idx] = $x;
 *   $arr []= $x;  // Append
 *
 * @param long The index of the element to be assigned.
 * @param object The element to be assigned.
 * @exception Invalid type for index.
 * @exception Non-existing index.
 * @exception Incorrect type of the element.
 */
PHP_METHOD(RepeatedField, offsetSet) {
  RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());
  upb_arena *arena = Arena_Get(&intern->arena);
  size_t size = upb_array_size(intern->array);
  zval *offset, *val;
  int64_t index;
  upb_msgval msgval;

  if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &offset, &val) != SUCCESS) {
    return;
  }

  if (Z_TYPE_P(offset) == IS_NULL) {
    index = size;
  } else if (!Convert_PhpToInt64(offset, &index)) {
    return;
  }

  if (!Convert_PhpToUpb(val, &msgval, intern->type, intern->desc, arena)) {
    return;
  }

  if (index > size) {
    zend_error(E_USER_ERROR, "Element at index %ld doesn't exist.\n", index);
  } else if (index == size) {
    upb_array_append(intern->array, msgval, Arena_Get(&intern->arena));
  } else {
    upb_array_set(intern->array, index, msgval);
  }
}

/**
 * RepeatedField::offsetUnset()
 *
 * Implements the ArrayAccess interface. Invoked when PHP code calls:
 *
 *   unset($arr[$idx]);
 *
 * @param long The index of the element to be removed.
 * @exception Invalid type for index.
 * @exception The element to be removed is not at the end of the RepeatedField.
 */
PHP_METHOD(RepeatedField, offsetUnset) {
  RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());
  zend_long index;
  zend_long size = upb_array_size(intern->array);

  // Only the element at the end of the array can be removed.
  if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) != SUCCESS) {
    return;
  }

  if (size == 0 || index != size - 1) {
    php_error_docref(NULL, E_USER_ERROR, "Cannot remove element at %ld.\n",
                     index);
    return;
  }

  upb_array_resize(intern->array, size - 1, Arena_Get(&intern->arena));
}

/**
 * RepeatedField::count()
 *
 * Implements the Countable interface. Invoked when PHP code calls:
 *
 *   $len = count($arr);
 * Return the number of stored elements.
 * This will also be called for: count($arr)
 * @return long The number of stored elements.
 */
PHP_METHOD(RepeatedField, count) {
  RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());

  if (zend_parse_parameters_none() == FAILURE) {
    return;
  }

  RETURN_LONG(upb_array_size(intern->array));
}

/**
 * RepeatedField::getIterator()
 *
 * Implements the IteratorAggregate interface. Invoked when PHP code calls:
 *
 *   foreach ($arr) {}
 *
 * @return object Beginning iterator.
 */
PHP_METHOD(RepeatedField, getIterator) {
  zval ret;
  RepeatedFieldIter_make(&ret, getThis());
  RETURN_ZVAL(&ret, 0, 1);
}

ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1)
  ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2)
  ZEND_ARG_INFO(0, index)
  ZEND_ARG_INFO(0, newval)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO(arginfo_void, 0)
ZEND_END_ARG_INFO()

static zend_function_entry repeated_field_methods[] = {
  PHP_ME(RepeatedField, __construct,  NULL,              ZEND_ACC_PUBLIC)
  PHP_ME(RepeatedField, append,       NULL,              ZEND_ACC_PUBLIC)
  PHP_ME(RepeatedField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC)
  PHP_ME(RepeatedField, offsetGet,    arginfo_offsetGet, ZEND_ACC_PUBLIC)
  PHP_ME(RepeatedField, offsetSet,    arginfo_offsetSet, ZEND_ACC_PUBLIC)
  PHP_ME(RepeatedField, offsetUnset,  arginfo_offsetGet, ZEND_ACC_PUBLIC)
  PHP_ME(RepeatedField, count,        arginfo_void,      ZEND_ACC_PUBLIC)
  PHP_ME(RepeatedField, getIterator,  arginfo_void,      ZEND_ACC_PUBLIC)
  ZEND_FE_END
};

// -----------------------------------------------------------------------------
// PHP RepeatedFieldIter
// -----------------------------------------------------------------------------

typedef struct {
  zend_object std;
  zval repeated_field;
  zend_long position;
} RepeatedFieldIter;

zend_class_entry *RepeatedFieldIter_class_entry;
static zend_object_handlers repeated_field_iter_object_handlers;

/**
 * RepeatedFieldIter_create()
 *
 * PHP class entry function to allocate and initialize a new RepeatedFieldIter
 * object.
 */
zend_object* RepeatedFieldIter_create(zend_class_entry *class_type) {
  RepeatedFieldIter *intern = emalloc(sizeof(RepeatedFieldIter));
  zend_object_std_init(&intern->std, class_type);
  intern->std.handlers = &repeated_field_iter_object_handlers;
  ZVAL_NULL(&intern->repeated_field);
  intern->position = 0;
  // Skip object_properties_init(), we don't allow derived classes.
  return &intern->std;
}

/**
 * RepeatedFieldIter_dtor()
 *
 * Object handler to destroy a RepeatedFieldIter. This releases all resources
 * associated with the message. Note that it is possible to access a destroyed
 * object from PHP in rare cases.
 */
static void RepeatedFieldIter_dtor(zend_object* obj) {
  RepeatedFieldIter* intern = (RepeatedFieldIter*)obj;
  zval_ptr_dtor(&intern->repeated_field);
  zend_object_std_dtor(&intern->std);
}

/**
 * RepeatedFieldIter_make()
 *
 * C function to create a RepeatedFieldIter.
 */
static void RepeatedFieldIter_make(zval *val, zval *repeated_field) {
  RepeatedFieldIter *iter;
  ZVAL_OBJ(val, RepeatedFieldIter_class_entry->create_object(
                    RepeatedFieldIter_class_entry));
  iter = (RepeatedFieldIter*)Z_OBJ_P(val);
  ZVAL_COPY(&iter->repeated_field, repeated_field);
}

/*
 * When a user writes:
 *
 *   foreach($arr as $key => $val) {}
 *
 * PHP's iterator protocol is:
 *
 *   $iter = $arr->getIterator();
 *   for ($iter->rewind(); $iter->valid(); $iter->next()) {
 *     $key = $iter->key();
 *     $val = $iter->current();
 *   }
 */

/**
 * RepeatedFieldIter::rewind()
 *
 * Implements the Iterator interface. Sets the iterator to the first element.
 */
PHP_METHOD(RepeatedFieldIter, rewind) {
  RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis());
  intern->position = 0;
}

/**
 * RepeatedFieldIter::current()
 *
 * Implements the Iterator interface. Returns the current value.
 */
PHP_METHOD(RepeatedFieldIter, current) {
  RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis());
  RepeatedField *field = (RepeatedField*)Z_OBJ_P(&intern->repeated_field);
  upb_array *array = field->array;
  zend_long index = intern->position;
  upb_msgval msgval;
  zval ret;

  if (index < 0 || index >= upb_array_size(array)) {
    zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index);
  }

  msgval = upb_array_get(array, index);

  Convert_UpbToPhp(msgval, &ret, field->type, field->desc, &field->arena);
  RETURN_ZVAL(&ret, 0, 1);
}

/**
 * RepeatedFieldIter::key()
 *
 * Implements the Iterator interface. Returns the current key.
 */
PHP_METHOD(RepeatedFieldIter, key) {
  RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis());
  RETURN_LONG(intern->position);
}

/**
 * RepeatedFieldIter::next()
 *
 * Implements the Iterator interface. Advances to the next element.
 */
PHP_METHOD(RepeatedFieldIter, next) {
  RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis());
  ++intern->position;
}

/**
 * RepeatedFieldIter::valid()
 *
 * Implements the Iterator interface. Returns true if this is a valid element.
 */
PHP_METHOD(RepeatedFieldIter, valid) {
  RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis());
  RepeatedField *field = (RepeatedField*)Z_OBJ_P(&intern->repeated_field);
  RETURN_BOOL(intern->position < upb_array_size(field->array));
}

static zend_function_entry repeated_field_iter_methods[] = {
  PHP_ME(RepeatedFieldIter, rewind,      arginfo_void, ZEND_ACC_PUBLIC)
  PHP_ME(RepeatedFieldIter, current,     arginfo_void, ZEND_ACC_PUBLIC)
  PHP_ME(RepeatedFieldIter, key,         arginfo_void, ZEND_ACC_PUBLIC)
  PHP_ME(RepeatedFieldIter, next,        arginfo_void, ZEND_ACC_PUBLIC)
  PHP_ME(RepeatedFieldIter, valid,       arginfo_void, ZEND_ACC_PUBLIC)
  ZEND_FE_END
};

// -----------------------------------------------------------------------------
// Module init.
// -----------------------------------------------------------------------------

/**
 * Array_ModuleInit()
 *
 * Called when the C extension is loaded to register all types.
 */
void Array_ModuleInit() {
  zend_class_entry tmp_ce;
  zend_object_handlers *h;

  // RepeatedField.
  INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\RepeatedField",
                   repeated_field_methods);

  RepeatedField_class_entry = zend_register_internal_class(&tmp_ce);
  zend_class_implements(RepeatedField_class_entry, 3, spl_ce_ArrayAccess,
                        zend_ce_aggregate, spl_ce_Countable);
  RepeatedField_class_entry->ce_flags |= ZEND_ACC_FINAL;
  RepeatedField_class_entry->create_object = RepeatedField_create;

  h = &RepeatedField_object_handlers;
  memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
  h->dtor_obj = RepeatedField_destructor;
  h->get_properties = RepeatedField_GetProperties;
  h->get_property_ptr_ptr = RepeatedField_GetPropertyPtrPtr;

  // RepeatedFieldIter
  INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\RepeatedFieldIter",
                   repeated_field_iter_methods);

  RepeatedFieldIter_class_entry = zend_register_internal_class(&tmp_ce);
  zend_class_implements(RepeatedFieldIter_class_entry, 1, zend_ce_iterator);
  RepeatedFieldIter_class_entry->ce_flags |= ZEND_ACC_FINAL;
  RepeatedFieldIter_class_entry->create_object = RepeatedFieldIter_create;

  h = &repeated_field_iter_object_handlers;
  memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
  h->dtor_obj = RepeatedFieldIter_dtor;
}
