/* 
 * Copyright 2008-2018 Aerospike, Inc.
 *
 * Portions may be licensed to Aerospike, Inc. under one or more contributor
 * license agreements.
 *
 * 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 <aerospike/as_arraylist.h>
#include <aerospike/as_arraylist_iterator.h>
#include <aerospike/as_iterator.h>
#include <aerospike/as_list.h>
#include <aerospike/as_list_iterator.h>

/*******************************************************************************
 *	EXTERN FUNCTIONS
 ******************************************************************************/

extern bool as_arraylist_release(as_arraylist *list);

/*******************************************************************************
 *	INSTANCE FUNCTIONS
 ******************************************************************************/

static bool _as_arraylist_list_destroy(as_list *l)
{
    return as_arraylist_release((as_arraylist *)l);
}

/*******************************************************************************
 *	VALUE FUNCTIONS
 ******************************************************************************/

static uint32_t _as_arraylist_list_hashcode(const as_list *l)
{
    return as_arraylist_hashcode((as_arraylist *)l);
}

static uint32_t _as_arraylist_list_size(const as_list *l)
{
    return as_arraylist_size((as_arraylist *)l);
}

/*******************************************************************************
 *	GET FUNCTIONS
 ******************************************************************************/

static as_val *_as_arraylist_list_get(const as_list *l, uint32_t i)
{
    return as_arraylist_get((as_arraylist *)l, i);
}

static int64_t _as_arraylist_list_get_int64(const as_list *l, uint32_t i)
{
    return as_arraylist_get_int64((as_arraylist *)l, i);
}

static double _as_arraylist_list_get_double(const as_list *l, uint32_t i)
{
    return as_arraylist_get_double((as_arraylist *)l, i);
}

static char *_as_arraylist_list_get_str(const as_list *l, uint32_t i)
{
    return as_arraylist_get_str((as_arraylist *)l, i);
}

/*******************************************************************************
 *	SET FUNCTIONS
 ******************************************************************************/

static int _as_arraylist_list_set(as_list *l, uint32_t i, as_val *v)
{
    return as_arraylist_set((as_arraylist *)l, i, v);
}

static int _as_arraylist_list_set_int64(as_list *l, uint32_t i, int64_t v)
{
    return as_arraylist_set_int64((as_arraylist *)l, i, v);
}

static int _as_arraylist_list_set_double(as_list *l, uint32_t i, double v)
{
    return as_arraylist_set_double((as_arraylist *)l, i, v);
}

static int _as_arraylist_list_set_str(as_list *l, uint32_t i, const char *v)
{
    return as_arraylist_set_str((as_arraylist *)l, i, v);
}

/*******************************************************************************
 *	INSERT FUNCTIONS
 ******************************************************************************/

static int _as_arraylist_list_insert(as_list *l, uint32_t i, as_val *v)
{
    return as_arraylist_insert((as_arraylist *)l, i, v);
}

static int _as_arraylist_list_insert_int64(as_list *l, uint32_t i, int64_t v)
{
    return as_arraylist_insert_int64((as_arraylist *)l, i, v);
}

static int _as_arraylist_list_insert_double(as_list *l, uint32_t i, double v)
{
    return as_arraylist_insert_double((as_arraylist *)l, i, v);
}

static int _as_arraylist_list_insert_str(as_list *l, uint32_t i, const char *v)
{
    return as_arraylist_insert_str((as_arraylist *)l, i, v);
}

/*******************************************************************************
 *	APPEND FUNCTIONS
 ******************************************************************************/

static int _as_arraylist_list_append(as_list *l, as_val *v)
{
    return as_arraylist_append((as_arraylist *)l, v);
}

static int _as_arraylist_list_append_int64(as_list *l, int64_t v)
{
    return as_arraylist_append_int64((as_arraylist *)l, v);
}

static int _as_arraylist_list_append_double(as_list *l, double v)
{
    return as_arraylist_append_double((as_arraylist *)l, v);
}

static int _as_arraylist_list_append_str(as_list *l, const char *v)
{
    return as_arraylist_append_str((as_arraylist *)l, v);
}

/*******************************************************************************
 *	PREPEND FUNCTIONS
 ******************************************************************************/

static int _as_arraylist_list_prepend(as_list *l, as_val *v)
{
    return as_arraylist_prepend((as_arraylist *)l, v);
}

static int _as_arraylist_list_prepend_int64(as_list *l, int64_t v)
{
    return as_arraylist_prepend_int64((as_arraylist *)l, v);
}

static int _as_arraylist_list_prepend_double(as_list *l, double v)
{
    return as_arraylist_prepend_double((as_arraylist *)l, v);
}

static int _as_arraylist_list_prepend_str(as_list *l, const char *v)
{
    return as_arraylist_prepend_str((as_arraylist *)l, v);
}

/*******************************************************************************
 *	REMOVE FUNCTION
 ******************************************************************************/

static int _as_arraylist_list_remove(as_list *l, uint32_t i)
{
    return as_arraylist_remove((as_arraylist *)l, i);
}

/*******************************************************************************
 *	ACCESSOR AND MODIFIER FUNCTIONS
 ******************************************************************************/

static int _as_arraylist_list_concat(as_list *l, const as_list *l2)
{
    return as_arraylist_concat((as_arraylist *)l, (const as_arraylist *)l2);
}

static int _as_arraylist_list_trim(as_list *l, uint32_t i)
{
    return as_arraylist_trim((as_arraylist *)l, i);
}

static as_val *_as_arraylist_list_head(const as_list *l)
{
    return as_arraylist_head((as_arraylist *)l);
}

static as_list *_as_arraylist_list_tail(const as_list *l)
{
    return (as_list *)as_arraylist_tail((as_arraylist *)l);
}

static as_list *_as_arraylist_list_drop(const as_list *l, uint32_t n)
{
    return (as_list *)as_arraylist_drop((as_arraylist *)l, n);
}

static as_list *_as_arraylist_list_take(const as_list *l, uint32_t n)
{
    return (as_list *)as_arraylist_take((as_arraylist *)l, n);
}

/*******************************************************************************
 *	ITERATION FUNCTIONS
 ******************************************************************************/

static bool _as_arraylist_list_foreach(const as_list *l,
                                       as_list_foreach_callback callback,
                                       void *udata)
{
    return as_arraylist_foreach((as_arraylist *)l, callback, udata);
}

static as_list_iterator *_as_arraylist_list_iterator_new(const as_list *l)
{
    return (as_list_iterator *)as_arraylist_iterator_new((as_arraylist *)l);
}

static as_list_iterator *_as_arraylist_list_iterator_init(const as_list *l,
                                                          as_list_iterator *it)
{
    return (as_list_iterator *)as_arraylist_iterator_init(
        (as_arraylist_iterator *)it, (as_arraylist *)l);
}

/*******************************************************************************
 *	HOOKS
 ******************************************************************************/

const as_list_hooks as_arraylist_list_hooks = {

    /***************************************************************************
	 *	instance hooks
	 **************************************************************************/

    .destroy = _as_arraylist_list_destroy,

    /***************************************************************************
	 *	info hooks
	 **************************************************************************/

    .hashcode = _as_arraylist_list_hashcode,
    .size = _as_arraylist_list_size,

    /***************************************************************************
	 *	get hooks
	 **************************************************************************/

    .get = _as_arraylist_list_get,
    .get_int64 = _as_arraylist_list_get_int64,
    .get_double = _as_arraylist_list_get_double,
    .get_str = _as_arraylist_list_get_str,

    /***************************************************************************
	 *	set hooks
	 **************************************************************************/

    .set = _as_arraylist_list_set,
    .set_int64 = _as_arraylist_list_set_int64,
    .set_double = _as_arraylist_list_set_double,
    .set_str = _as_arraylist_list_set_str,

    /***************************************************************************
	 *	insert hooks
	 **************************************************************************/

    .insert = _as_arraylist_list_insert,
    .insert_int64 = _as_arraylist_list_insert_int64,
    .insert_double = _as_arraylist_list_insert_double,
    .insert_str = _as_arraylist_list_insert_str,

    /***************************************************************************
	 *	append hooks
	 **************************************************************************/

    .append = _as_arraylist_list_append,
    .append_int64 = _as_arraylist_list_append_int64,
    .append_double = _as_arraylist_list_append_double,
    .append_str = _as_arraylist_list_append_str,

    /***************************************************************************
	 *	prepend hooks
	 **************************************************************************/

    .prepend = _as_arraylist_list_prepend,
    .prepend_int64 = _as_arraylist_list_prepend_int64,
    .prepend_double = _as_arraylist_list_prepend_double,
    .prepend_str = _as_arraylist_list_prepend_str,

    /***************************************************************************
	 *	remove hook
	 **************************************************************************/

    .remove = _as_arraylist_list_remove,

    /***************************************************************************
	 *	accessor and modifier hooks
	 **************************************************************************/

    .concat = _as_arraylist_list_concat,
    .trim = _as_arraylist_list_trim,
    .head = _as_arraylist_list_head,
    .tail = _as_arraylist_list_tail,
    .drop = _as_arraylist_list_drop,
    .take = _as_arraylist_list_take,

    /***************************************************************************
	 *	iteration hooks
	 **************************************************************************/

    .foreach = _as_arraylist_list_foreach,
    .iterator_new = _as_arraylist_list_iterator_new,
    .iterator_init = _as_arraylist_list_iterator_init,

};
