/* $Id$ 
 * 
 * Licensed to the Apache Software Foundation (ASF) under one or more 
 * contributor license agreements. See the NOTICE file distributed with  
 * this work for additional information regarding copyright ownership. 
 * The ASF licenses this file to you 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. 
 */ 

/*  
 * etch_arrayval.c -- etch_arrayvalue implementation.
 *
 * todo: modify this class to permit using an etch_nativearray as the arrayvalue
 * backing store. this could be very useful for large arrays of small values,
 * where not all values are accessed individually. the key to this conversion  
 * is always returning a non-disposable object from get(), and we ensure this
 * by always returnings item[i] from the arraylist. when a get(i) is requested,
 * we check the arraylist first, lazy-allocating it if necessary. if arraylist[i]
 * is null, we populate arraylist[i] from natarray[i]. we then return arraylist[i]
 * which is always non-disposable.
 */

#include "etch_arrayval.h"
#include "etch_global.h"
#include "etch_syncobj.h"
#include "etch_tagdata.h"
#include "etchexcp.h"

etch_arrayvalue* new_arrayvalue_init(const int, const int, const int, const int);
etch_arrayvalue* populate_arrayvalue_from(etch_arrayvalue*);
unsigned short etch_itemtype_to_arrayclass(unsigned short item_obj_type);
int  array_value_add(etch_arrayvalue* thisp, ETCH_ARRAY_ELEMENT* content);



/**
 * new_arrayvalue()
 * primary constructor for etch_arrayvalue
 * @param type_code wire ID of the array content class.
 * @param custom_struct_type non-disposable type of custom struct, 
   caller retains ownership as with all types.
 */
etch_arrayvalue* new_arrayvalue (const byte type_code, etch_type* custom_struct_type, 
    const int dim, const int initsize, const int deltsize, 
    const int is_readonly, const int is_synchronized)
{
    etch_arrayvalue* newobj = new_arrayvalue_init
        (initsize, deltsize, is_readonly, is_synchronized);

    newobj->dim = dim;
    newobj->type_code = type_code;
    newobj->class_id  = etch_arraytype_to_classid (type_code);

    newobj->custom_struct_type = custom_struct_type; /* not owned */

    return newobj;
}


/**
 * new_arrayvalue_from()
 * etch_arrayvalue constructor - builds arryavalue from an etch_nativearray.
 * when native array is multi-dimensioned, this constructor is invoked recursively.
 * todo: convert this to use the subarray call, which this code duplicates.
 * todo: add a parameter to permit the arrayvalue to remain unpopulated; i.e.,
 * the nativearray is present but the object array is not yet populated.
 */
etch_arrayvalue* new_arrayvalue_from (etch_nativearray* natarray,  
    const signed char type_code, etch_type* custom_struct_type, 
    const int initsize, const int deltsize, const int is_readonly)  
{
    const int    SUBARRAY_NUMDIMS = natarray->numdims - 1;
    const size_t SUBARRAY_COUNT   = natarray->dimension[SUBARRAY_NUMDIMS];
    const size_t SUBARRAY_BYTELEN = natarray->dimsize  [SUBARRAY_NUMDIMS];

    int i = 0;
    etch_arrayvalue* newav = NULL;  /* nativearray currently max 3 dims*/
    if (natarray->is_null) return NULL;
    if (SUBARRAY_NUMDIMS < 0 || SUBARRAY_NUMDIMS > 2) return NULL;

    newav = new_arrayvalue_init(initsize, deltsize, is_readonly, FALSE);
    newav->is_array_owned  = !is_readonly;   /* does av own nativearray */
    newav->type_code = type_code;       /* external array content type */
    newav->class_id  = etch_arraytype_to_classid (type_code);
    newav->natarray  = natarray;
    newav->dim       = natarray->numdims;
    newav->class_id  = natarray->class_id;  /* validator expects class match */

    newav->custom_struct_type = custom_struct_type;  /* not owned */

    if  (SUBARRAY_NUMDIMS == 0) /* if single dimension, populate values */
    {
         newav = populate_arrayvalue_from(newav);
    }
    else 
    {   newav->content_obj_type  = ETCHTYPEB_ARRAYVAL;
        newav->content_item_size = sizeof(void*);

        for(; i < (const int) SUBARRAY_COUNT; i++)      
        {
            /* the native array was multi-dimensioned. we therefore add values    
             * to this arrayvalue, which are arrayalues of one dimension less than
             * that of the parent arrayvalue. the sub-arrayvalues are created from 
             * etch_nativearrays created from offset pointers into the parent
             * native array byte vector. sub-arrays therefore do not own content.
             */
            const int itemcount = (int) natarray->dimension[SUBARRAY_NUMDIMS-1];
            const size_t vector_offset = i * SUBARRAY_BYTELEN;
            byte* subvector = (byte*) natarray->values + vector_offset;
            etch_arrayvalue* subav = NULL;

            /* create a sub-array. note we pass a possibly unused dimension   
             * value in order to avoid the extra logic to not do so */
            etch_nativearray* newarray = new_nativearray_from(subvector, natarray->class_id, 
                natarray->itemsize, SUBARRAY_NUMDIMS,  
                (int) natarray->dimension[0], (int) natarray->dimension[1], 0);

            newarray->content_class_id  = natarray->content_class_id;
            newarray->content_obj_type  = natarray->content_obj_type;
            newarray->is_content_owned  = FALSE; /* pointer into parent vector */
            newarray->counts[0] = newarray->counts[0];  /* move counts in case */
            newarray->counts[1] = newarray->counts[1]; /* caller is using them */
            newarray->counts[2] = 0;
           
            subav = new_arrayvalue_from  /* recursively create a sub-arrayvalue */
                (newarray, type_code, custom_struct_type, itemcount, 0, is_readonly);
            
            arrayvalue_add(newav, (ETCH_ARRAY_ELEMENT*) subav); 
        }
    }

    return newav;
}


/**
 * new_arrayvalue_default()
 * default constructor for etch_arrayvalue
 */
etch_arrayvalue* new_arrayvalue_default ()
{
    etch_arrayvalue* newobj = new_arrayvalue_init
        (ETCH_ARRAYVALUE_DEFAULT_INITSIZE, 
         ETCH_ARRAYVALUE_DEFAULT_DELTSIZE, 
         ETCH_ARRAYVALUE_DEFAULT_READONLY,
         ETCH_ARRAYVALUE_DEFAULT_SYNCHRONIZED);

    return newobj;
}


/**
 * new_arrayvalue_init() 
 * common initialization on etch_arrayvalue construction.
 */
etch_arrayvalue* new_arrayvalue_init (const int initsize, const int deltsize, 
    const int is_readonly, const int is_synchronized)
{
    etch_arrayvalue* newobj = (etch_arrayvalue*) new_object(sizeof(etch_arrayvalue), 
         ETCHTYPEB_ARRAYVAL, CLASSID_ARRAYVALUE);

    newobj->destroy = destroy_arrayvalue;
    newobj->clone   = clone_null;

    /* the underlying arraylist is marked as content type object, meaning we can
     * interpret content as etchobject and call methods on the object accordingly,
     * most notably destroy(). when is_readonly is true, the underlying list will
     * not free memory for its content when the list is destroyed.
     */
    newobj->list = new_arrayvalue_arraylist
        (initsize, deltsize, is_readonly, is_synchronized);  

    return newobj;
}


/**
 * destroy_array_value()
 * destructor for an etch_arrayvalue object
 */
int destroy_arrayvalue (etch_arrayvalue* thisp)
{
    if ((thisp->refcount > 0) && (--thisp->refcount > 0)) return -1;   

    if (!is_etchobj_static_content(thisp))
    {
        if (thisp->natarray && thisp->is_array_owned) 
            thisp->natarray->destroy(thisp->natarray);

        if (thisp->list)
            thisp->list->destroy(thisp->list);
    }

    destroy_objectex((objmask*)thisp);      
    return 0;
}


/** 
 * populate_arrayvalue_from()
 * populate the specified arrayvalue from its attached single-dimensioned native array
 */
etch_arrayvalue* populate_arrayvalue_from (etch_arrayvalue* av)  
{
    etch_nativearray* nat = av->natarray;
    const int numentries  = (int) nat->dimension[0];
    objmask* wrapped_value = NULL;
    int i = 0, result = 0;
    if (nat->numdims != 1) return NULL;

    av->content_obj_type  = nat->content_obj_type;
    av->content_item_size = (short) nat->itemsize;

    for(; i < numentries; i++)
    {  
        result = etch_nativearray_get_wrapped_component(nat, i, &wrapped_value); 
        arrayvalue_add(av, (ETCH_ARRAY_ELEMENT*) wrapped_value); 
    }    

    return av;
}


/**
 * arrayvalue3_to_nativearray()
 * convert an arrayvalue of dimension 3 to a native array. assumes that an
 * appropriately sized and configured etch_nativearray object is resident in
 * the arrayvalue object.
 */
int arrayvalue3_to_nativearray(etch_arrayvalue* av2)
{
    const int item2count = arrayvalue_count(av2);
    int item1count = 0, item0count = 0;
    etch_nativearray* natv = av2->natarray;
    etch_object* wrapper = NULL;
    etch_arrayvalue *av1 = NULL, *av0 = NULL;
    int i, j, k, items=0; 

    for(i=0; i < item2count; i++)
    {    
        av1 = arrayvalue_get(av2, i);
        if (!is_etch_arrayvalue(av1)) return -1; 
        item1count = arrayvalue_count(av1);

        for(j=0; j < (const int) item1count; j++)
        {   
            av0 = arrayvalue_get(av1, j);
            if (!is_etch_arrayvalue(av0)) return -1; 
            item0count = arrayvalue_count(av0);

            for(k=0; k < (const int) item0count; k++)
            {  /* insert native values into nativearray byte vector. we mask the
                * wrapped primitive with an etch_object. we can do so because the
                * etch primitive object is guaranteed to offset its value the
                * same as that of an etch_object, right after the object header. 
                */ 
                if (NULL == (wrapper = arrayvalue_get(av0, k))) return -1;
                if (0 == natv->put3(natv, &wrapper->value, i, j, k))
                    items++;
                else return -1;
            }   
        }    
    }    

    return items;
}


/**
 * arrayvalue2_to_nativearray()
 * convert an arrayvalue of dimension 2 to a native array. assumes that an
 * appropriately sized and configured etch_nativearray object is resident in
 * the arrayvalue object.
 */
int arrayvalue2_to_nativearray(etch_arrayvalue* av1)
{
    const int item1count = arrayvalue_count(av1);
    int item0count = 0;
    etch_nativearray* natv = av1->natarray;
    etch_object* wrapper = NULL;
    etch_arrayvalue *av0 = NULL;
    int i, j, items=0; 

    for(i = 0; i < item1count; i++)
    {    
        av0 = arrayvalue_get(av1, i);
        if (!is_etch_arrayvalue(av0)) return -1; 
        item0count = arrayvalue_count(av0);

        for(j = 0; j < (const int) item0count; j++)
        {   /* insert native values into nativearray byte vector. we mask the
             * wrapped primitive with an etch_object. we can do so because the
             * etch primitive object is guaranteed to offset its value the
             * same as that of an etch_object, right after the object header. 
             */ 
            if (NULL == (wrapper = arrayvalue_get(av0, j))) return -1;
            if (0 == natv->put2(natv, &wrapper->value, i, j))
                items++;
            else return -1;        
        }   
    }    

    return items;
}


/**
 * arrayvalue1_to_nativearray()
 * convert an arrayvalue of dimension 1 to a native array. assumes that an
 * appropriately sized and configured etch_nativearray object is resident in
 * the arrayvalue object.
 */
int arrayvalue1_to_nativearray(etch_arrayvalue* av)
{
    const int itemcount = arrayvalue_count(av);
    etch_nativearray* natv = av->natarray;
    etch_object* wrapper = NULL;
    int i=0, items = 0;  
   
    for(; i < itemcount; i++)
    {   /* insert native values into nativearray byte vector. we mask the
         * wrapped primitive with an etch_object. we can do so because the
         * etch primitive object is guaranteed to offset its value the
         * same as that of an etch_object, right after the object header. 
         */ 
        if (NULL == (wrapper = arrayvalue_get(av, i))) return -1;
        if (0 == natv->put1(natv, &wrapper->value, i))
            items++;
        else return -1;    
    }

    return items;
}


/**
 * arrayvalue_to_nativearray()
 * convert an arrayvalue to a native array
 * if the arrayvalue is created from a native array, the source native array is
 * still resident, however this method assumes we want to create the native array
 * regardless of whether one is resident. is also assumes that if we have created
 * the arrayvalue from scratch, we have done so properly, i.e., a multi-dimensioned
 * arrayvalue is and arrayvalue of arrayvalues. It additionally assumes that the
 * arrayvalue is populated with at least one value; if this were not the case we  
 * would need to switch on the byte type_code to determine the item size.
 */
int arrayvalue_to_nativearray (etch_arrayvalue* av)
{
    int dim0count=0, dim1count=0, dim2count=0, itemsize=0;
    etch_arrayvalue *av2 = NULL, *av1 = NULL, *av0 = NULL;
    unsigned short array_class_id = 0;
    etch_nativearray* newna = NULL;
    const int dimensions = av->dim;

    switch(dimensions)  /* determine native array size */
    {   case 1:
            av0 = av;
            break;

        case 2:
            dim1count = arrayvalue_count(av);
            av1 = (etch_arrayvalue*) arrayvalue_get(av, 0);
            if (is_etch_arrayvalue(av1)) 
                av0 = av1;
            break;

        case 3:
            dim2count = arrayvalue_count(av);
            av2 = (etch_arrayvalue*) arrayvalue_get(av, 0);
            if (!is_etch_arrayvalue(av2)) break;

            dim1count = arrayvalue_count(av2);
            av1 = (etch_arrayvalue*) arrayvalue_get(av2, 0);
            if (is_etch_arrayvalue(av1)) 
                av0 = av1;
    }

    if (av0) /* if arrayvalue was populated ... */
    {   itemsize  = av0->content_item_size;
        dim0count = arrayvalue_count(av0);
        array_class_id = etch_itemtype_to_arrayclass(av0->content_obj_type);
    }

    if (dim0count == 0 || itemsize == 0) return NULL;  /* bad arrayvalue */

    newna = new_nativearray  /* allocate appropriately sized native array */
       (array_class_id, itemsize, dimensions, dim0count, dim1count, dim2count);
    if (NULL == newna) return NULL;

    /* if previous native array was attached to the arrayvalue, free it */
    if (av->natarray) av->natarray->destroy(av->natarray);

    av->natarray = newna;  /* attach new native array to its arrayvalue */

    switch(dimensions)    /* populate new native array from array value */
    {   case 1: return arrayvalue1_to_nativearray(av);
        case 2: return arrayvalue2_to_nativearray(av);  
        case 3: return arrayvalue3_to_nativearray(av);  
    }

    return NULL;
}


/**
 * arrayvalue_add()
 * returns 0 or -1
 */
int arrayvalue_add (etch_arrayvalue* av, ETCH_ARRAY_ELEMENT* content)
{
    const int result = arraylist_add(av->list, content);
    return result;
}


/**
 * array_value_add()
 * returns 0 or -1
 */
int array_value_add (etch_arrayvalue* av, ETCH_ARRAY_ELEMENT* content)
{
    const int result = arraylist_add(av->list, content);
    return result;
}


/**
 * arrayvalue_get()
 * return item at specified index
 * returns array item, always an address, or NULL.
 */
void* arrayvalue_get (etch_arrayvalue* thisp, const int i) 
{
    return arraylist_get(thisp->list, i);
}


/**
 * arrayvalue_count()
 * return item count
 */
int arrayvalue_count (etch_arrayvalue* thisp)
{
    return thisp? thisp->list? thisp->list->count: 0: 0;
}


/**
 * new_arrayvalue_arraylist()
 * allocates and returns an arraylist configured appropriately for use as arrayvalue backing store
 */
etch_arraylist* new_arrayvalue_arraylist (const int initsize, const int deltsize, 
    const int is_readonly, const int is_synchronized)
{
    etch_arraylist* list = is_synchronized? 
        new_synchronized_arraylist(initsize, deltsize):
        new_arraylist(initsize, deltsize);

    list->is_readonly = is_readonly != 0;  
    list->content_type = ETCHARRAYLIST_CONTENT_OBJECT;
    return list;
}


/**
 * new_array_element()
 * as ported from java, used when populating an array with nonspecific objects.
 */
ETCH_ARRAY_ELEMENT* new_array_element (const int objtype)
{
   return new_etch_object(CLASSID_ARRAYELEMENT, NULL);
}


static const signed char etch_primitive_typecodes[11] 
 = {ETCH_XTRNL_TYPECODE_CUSTOM,       /* CLASSID_ARRAY_OBJECT */
    ETCH_XTRNL_TYPECODE_BYTE,         /* CLASSID_ARRAY_BYTE   */
    ETCH_XTRNL_TYPECODE_BOOLEAN_TRUE, /* CLASSID_ARRAY_BOOL   */
    ETCH_XTRNL_TYPECODE_BYTE,         /* CLASSID_ARRAY_BYTE   */
    ETCH_XTRNL_TYPECODE_SHORT,        /* CLASSID_ARRAY_INT16  */
    ETCH_XTRNL_TYPECODE_INT,          /* CLASSID_ARRAY_INT32  */
    ETCH_XTRNL_TYPECODE_LONG,         /* CLASSID_ARRAY_INT64  */
    ETCH_XTRNL_TYPECODE_FLOAT,        /* CLASSID_ARRAY_FLOAT  */
    ETCH_XTRNL_TYPECODE_DOUBLE,       /* CLASSID_ARRAY_DOUBLE */
    ETCH_XTRNL_TYPECODE_STRING,       /* CLASSID_ARRAY_STRING */
    0,        
   };

static const unsigned short etch_arrayval_classids[11] 
 = {CLASSID_ARRAY_OBJECT,       /* ETCH_XTRNL_TYPECODE_CUSTOM */
    CLASSID_ARRAY_BYTE,         /* ETCH_XTRNL_TYPECODE_BYTE   */
    CLASSID_ARRAY_BOOL,         /* ETCH_XTRNL_TYPECODE_BOOLEAN_TRUE */
    CLASSID_ARRAY_BYTE,         /* ETCH_XTRNL_TYPECODE_BYTE   */
    CLASSID_ARRAY_INT16,        /* ETCH_XTRNL_TYPECODE_SHORT  */
    CLASSID_ARRAY_INT32,        /* ETCH_XTRNL_TYPECODE_INT    */
    CLASSID_ARRAY_INT64,        /* ETCH_XTRNL_TYPECODE_LONG   */
    CLASSID_ARRAY_FLOAT,        /* ETCH_XTRNL_TYPECODE_FLOAT  */
    CLASSID_ARRAY_DOUBLE,       /* ETCH_XTRNL_TYPECODE_DOUBLE */
    CLASSID_ARRAY_STRING,       /* ETCH_XTRNL_TYPECODE_STRING */
    0,
   };


/**
 * etch_arraytype_to_classid()
 * returns array class ID corresponding to serialization byte code.
 */
unsigned short etch_arraytype_to_classid (const signed char typecode)
{
    int i = 0;
    unsigned short idout = 0;
    signed char* p = (signed char*) etch_primitive_typecodes;

    for(; *p; i++, p++)
        if (*p == typecode)
        {   idout = etch_arrayval_classids[i];
            break;
        }

    return idout;
}


/**
 * etch_classid_to_arraytype()
 * returns serialization bytecode corresponding to array class ID
 */
signed char etch_classid_to_arraytype (const unsigned short class_id)
{
    int i = 0;
    signed char typecodeout = 0;
    unsigned short* p = (unsigned short*) etch_arrayval_classids;

    for(; *p; i++, p++)
        if (*p == class_id)
        {   typecodeout = etch_primitive_typecodes[i];
            break;
        }

    return typecodeout;
}


/**
 * etch_itemtype_to_arrayclass()
 * returns array object type corresponding to item object type 
 */
unsigned short etch_itemtype_to_arrayclass(unsigned short item_obj_type)
{ 
    if  (item_obj_type > 0 && item_obj_type <= ETCHTYPEB_STRING) 
         return etch_arrayval_classids[item_obj_type]; 
    else return CLASSID_ARRAY_OBJECT;
}


/**
 * arrayvalue_get_external_typecode() 
 * returns an array type bytecode for the specified array content type.
 */
signed char arrayvalue_get_external_typecode (unsigned short obj_type, unsigned short class_id)
{
    signed char xtype = 0;

    #if(0) /* uncompiled arrays are here for documentation purposes */

    unsigned short primitive_class_ids[] =
    {   CLASSID_ANY,             /* 0x0 */              
        CLASSID_PRIMITIVE_BYTE,  /* 0x1 */
        CLASSID_PRIMITIVE_BOOL,  /* 0x2 */
        CLASSID_PRIMITIVE_INT8,  /* 0x3 */
        CLASSID_PRIMITIVE_INT16, /* 0x4 */
        CLASSID_PRIMITIVE_INT32, /* 0x5 */
        CLASSID_PRIMITIVE_INT64, /* 0x6 */
        CLASSID_PRIMITIVE_FLOAT, /* 0x7 */
        CLASSID_PRIMITIVE_DOUBLE,/* 0x8 */
        CLASSID_STRING,          /* 0x9 */
    };

    unsigned short primitive_obj_types[] =
    {   ETCHTYPEB_UNDEFINED, /* 0x0 */   
        ETCHTYPEB_BYTE,      /* 0x1 */
        ETCHTYPEB_BOOL,      /* 0x2 */  
        ETCHTYPEB_INT8,      /* 0x3 */    
        ETCHTYPEB_INT16,     /* 0x4 */     
        ETCHTYPEB_INT32,     /* 0x5 */  
        ETCHTYPEB_INT64,     /* 0x6 */   
        ETCHTYPEB_IEEE32,    /* 0x7 */  
        ETCHTYPEB_IEEE64,    /* 0x8 */      
        ETCHTYPEB_STRING,    /* 0x9 */     
    };

    #endif

    if (obj_type == ETCHTYPEB_PRIMITIVE)
    {   if (class_id < 1 || class_id > 9)
            class_id = 0;

        xtype = etch_primitive_typecodes [class_id];
    }    
    else /* primitive obj_type? */
    if (obj_type > 0 && obj_type <= 9)
        xtype = etch_primitive_typecodes [obj_type];

    else switch(obj_type)
    {   case ETCHTYPEB_STRUCTVAL:   xtype = ETCH_XTRNL_TYPECODE_CUSTOM; break; 
        case ETCHTYPEB_ARRAYVAL:    xtype = ETCH_XTRNL_TYPECODE_ARRAY;  break;
        case ETCHTYPEB_NATIVEARRAY: xtype = ETCH_XTRNL_TYPECODE_ARRAY;  break;
        default: xtype = ETCH_XTRNL_TYPECODE_CUSTOM;   
    }
    
    return xtype;
}


/* 
 * arrayvalue_set_static_content()
 * configure arraylist of object wrappers such that objects are not freed by the arraylist
 * destructor. presumably this would be used during recursive access to arrayvalue, where
 * lowest level objects are seen and destroyed prior to higher level objects such as the
 * array wrappers. 
 */
void arrayvalue_set_static_content (etch_arrayvalue* av, const int is_set)
{
    etch_arraylist* list = av? av->list: NULL;
    if (list) list->is_readonly = is_set? TRUE: FALSE;
}


/* 
 * arrayvalue_set_iterator()
 * set an iterator on the arrayvalue, which becomes an iterator on its list
 */
int arrayvalue_set_iterator (etch_arrayvalue* av, etch_iterator* iterator)
{
    return set_iterator (iterator, av->list, &av->list->iterable);
}

