/*
*******************************************************************************
*
*   Copyright (C) 2000, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*
* File reslist.c
*
* Modification History:
*
*   Date        Name        Description
*   02/21/00    weiv        Creation.
*******************************************************************************
*/

#include "reslist.h"
#include "unewdata.h"
#include "unicode/ures.h"
#include "error.h"

#define BIN_ALIGNMENT 16

uint32_t res_write(UNewDataMemory *mem, struct SResource *res, 
                 uint32_t usedOffset, UErrorCode *status);

static const UDataInfo dataInfo={
    sizeof(UDataInfo),
    0,

    U_IS_BIG_ENDIAN,
    U_CHARSET_FAMILY,
    sizeof(UChar),
    0,

    0x52, 0x65, 0x73, 0x42,     /* dataFormat="resb" */
    1, 0, 0, 0,                 /* formatVersion */
    1, 4, 0, 0                  /* dataVersion take a look at version inside parsed resb*/
};

static uint8_t calcPadding(uint32_t size) {
    /* returns space we need to pad */
    return (uint8_t)((size%sizeof(uint32_t))?(sizeof(uint32_t)-(size%sizeof(uint32_t))):0);

}

/* Writing Functions */
static uint32_t string_write(UNewDataMemory *mem, struct SResource *res, 
                 uint32_t usedOffset, UErrorCode *status) {
    udata_write32(mem, res->u.fString.fLength);
    udata_writeUString(mem, res->u.fString.fChars, (res->u.fString.fLength)+1);
    udata_writePadding(mem, calcPadding(res->fSize));
    return usedOffset;
}

static uint32_t array_write(UNewDataMemory *mem, struct SResource *res, 
                 uint32_t usedOffset, UErrorCode *status) {
    uint32_t i = 0;
    uint32_t *resources = NULL;
    struct SResource *current = NULL;

    if(U_FAILURE(*status)) {
        return 0;
    }

    if(res->u.fArray.fCount > 0) {

        resources = (uint32_t *) uprv_malloc(sizeof(uint32_t)*res->u.fArray.fCount);
        if (resources == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }

        current = res->u.fArray.fFirst;
        i=0;

        while(current != NULL) {
            if(current->fType == RES_INT) {
                *(resources+i) = (current->fType)<<28 | (current->u.fIntValue.fValue & 0xFFFFFFF);
            } else if(current->fType == RES_BINARY) {
                uint32_t uo = usedOffset;
                usedOffset = res_write(mem, current, usedOffset, status);
                *(resources+i) = (current->fType)<<28 | (usedOffset>>2) ;
                usedOffset += (current->fSize) + calcPadding(current->fSize) - (usedOffset-uo);
            } else {
                usedOffset = res_write(mem, current, usedOffset, status);
                *(resources+i) = (current->fType)<<28 | (usedOffset>>2);
                usedOffset += (current->fSize) + calcPadding(current->fSize);
            }
            i++;
            current = current->fNext;
        }

        /* usedOffset += res->fSize + pad; */

        udata_write32(mem, res->u.fArray.fCount);

        udata_writeBlock(mem, resources, sizeof(uint32_t)*res->u.fArray.fCount);

        uprv_free(resources);
    } else { /*table is empty*/
        udata_write32(mem, 0);
    }
    return usedOffset;
}

static uint32_t intvector_write(UNewDataMemory *mem, struct SResource *res, 
                 uint32_t usedOffset, UErrorCode *status) {
    return usedOffset;
}

static uint32_t bin_write(UNewDataMemory *mem, struct SResource *res, 
                 uint32_t usedOffset, UErrorCode *status) {
    uint32_t pad = 0;
    uint32_t extrapad = calcPadding(res->fSize);
    uint32_t dataStart = usedOffset+sizeof(res->u.fBinaryValue.fLength);
    if(dataStart%BIN_ALIGNMENT) {
        pad = (BIN_ALIGNMENT-dataStart%BIN_ALIGNMENT);
        udata_writePadding(mem, pad);
        usedOffset += pad;
    }

    udata_write32(mem, res->u.fBinaryValue.fLength);
    udata_writeBlock(mem, res->u.fBinaryValue.fData, res->u.fBinaryValue.fLength);
    udata_writePadding(mem, (BIN_ALIGNMENT - pad + extrapad));
    return usedOffset;
}

static uint32_t int_write(UNewDataMemory *mem, struct SResource *res, 
                 uint32_t usedOffset, UErrorCode *status) {
    return usedOffset;
}


static uint32_t table_write(UNewDataMemory *mem, struct SResource *res, 
                 uint32_t usedOffset, UErrorCode *status) {
    uint8_t pad = 0;
    uint32_t i = 0;
    uint16_t *keys = NULL;
    uint32_t *resources = NULL;
    struct SResource *current = NULL;

    if(U_FAILURE(*status)) {
        return 0;
    }

    pad = calcPadding(res->fSize);

    if(res->u.fTable.fCount > 0) {

        keys = (uint16_t *) uprv_malloc(sizeof(uint16_t)*res->u.fTable.fCount);
        if (keys == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }

        resources = (uint32_t *) uprv_malloc(sizeof(uint32_t)*res->u.fTable.fCount);
        if (resources == NULL) {
            uprv_free(keys);
            *status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }

        current = res->u.fTable.fFirst;
        i=0;

        while(current != NULL) {
            *(keys+i) = (uint16_t)((current->fKey)+sizeof(uint32_t)); /*where the key is plus root pointer*/
            if(current->fType == RES_INT) {
                *(resources+i) = (current->fType)<<28 | (current->u.fIntValue.fValue & 0xFFFFFFF);
            } else if(current->fType == RES_BINARY) {
                uint32_t uo = usedOffset;
                usedOffset = res_write(mem, current, usedOffset, status);
                *(resources+i) = (current->fType)<<28 | (usedOffset>>2) ;
                usedOffset += (current->fSize) + calcPadding(current->fSize) - (usedOffset-uo);
            } else {
                usedOffset = res_write(mem, current, usedOffset, status);
                *(resources+i) = (current->fType)<<28 | (usedOffset>>2) ;
                usedOffset += (current->fSize) + calcPadding(current->fSize);
            }
            i++;
            current = current->fNext;
        }

        udata_write16(mem, res->u.fTable.fCount);

        udata_writeBlock(mem, keys, sizeof(uint16_t)*res->u.fTable.fCount);
        udata_writePadding(mem, pad);
        udata_writeBlock(mem, resources, sizeof(uint32_t)*res->u.fTable.fCount);

        uprv_free(keys);
        uprv_free(resources);
    } else { /*table is empty*/
        udata_write16(mem, 0);
        udata_writePadding(mem, pad);
    }
    return usedOffset;

}

uint32_t res_write(UNewDataMemory *mem, struct SResource *res, 
                 uint32_t usedOffset, UErrorCode *status) {

    if(U_FAILURE(*status)) {
        return 0;
    }

    if(res != NULL) {
        switch(res->fType) {
        case RES_STRING:
            return string_write(mem, res, usedOffset, status);
            break;
        case RES_INT_VECTOR:
            return intvector_write(mem, res, usedOffset, status);
            break;
        case RES_BINARY:
            return bin_write(mem, res, usedOffset, status);
            break;
        case RES_INT:
            return int_write(mem, res, usedOffset, status);
            break;
        case RES_ARRAY:
            return array_write(mem, res, usedOffset, status);
            break;
        case RES_TABLE : 
            return table_write(mem, res, usedOffset, status);
            break;
        default:
            break;
        }
    }
    *status = U_INTERNAL_PROGRAM_ERROR;
    return 0;
}


/*void bundle_write(struct SRBRoot *bundle, const char *outputDir, const char *filename, UErrorCode *status) {*/
void bundle_write(struct SRBRoot *bundle, const char *outputDir, UErrorCode *status) {
    UNewDataMemory *mem = NULL;
    uint8_t pad = 0;
    uint32_t root = 0;
    uint32_t usedOffset = 0;

    if(U_FAILURE(*status)) {
        return;
    }

    mem = udata_create(outputDir, "res", bundle->fLocale, &dataInfo, U_COPYRIGHT_STRING, status);
    /*mem = udata_create(outputDir, "res", filename, &dataInfo, U_COPYRIGHT_STRING, status);*/

    pad = calcPadding(bundle->fKeyPoint);

    usedOffset = sizeof(uint32_t) + bundle->fKeyPoint + pad ; /*this is how much root and keys are taking up*/

    root = ((usedOffset + bundle->fRoot->u.fTable.fChildrenSize)>>2) | (RES_TABLE << 28); /* we're gonna put the main table at the end */

    udata_write32(mem, root);

    udata_writeBlock(mem, bundle->fKeys, bundle->fKeyPoint);

    udata_writePadding(mem, pad);

    usedOffset = res_write(mem, bundle->fRoot, usedOffset, status);

    udata_finish(mem, status);

}


/* Opening Functions */

struct SResource* table_open(struct SRBRoot *bundle, char *tag, UErrorCode *status) {

    struct SResource *res;

    if(U_FAILURE(*status)) {
        return NULL;
    }

    res = (struct SResource *)uprv_malloc(sizeof(struct SResource));

    if(res == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }

    res->fType = RES_TABLE;
    res->fKey = bundle_addtag(bundle, tag, status);

    if(U_FAILURE(*status)) {
        uprv_free(res);
        return NULL;
    }

    res->fNext = NULL;
    res->fSize = sizeof(uint16_t);
    res->u.fTable.fCount = 0;
    res->u.fTable.fChildrenSize = 0;
    res->u.fTable.fFirst = NULL;
    res->u.fTable.fRoot = bundle;

    return res;
}

struct SResource* array_open(struct SRBRoot *bundle, char *tag, UErrorCode *status) {

    struct SResource *res;

    if(U_FAILURE(*status)) {
        return NULL;
    }

    res = (struct SResource *)uprv_malloc(sizeof(struct SResource));

    if(res == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }

    res->fType = RES_ARRAY;
    res->fKey = bundle_addtag(bundle, tag, status);

    if(U_FAILURE(*status)) {
        uprv_free(res);
        return NULL;
    }

    res->fNext = NULL;
    res->fSize = sizeof(int32_t);
    res->u.fArray.fCount = 0;
    res->u.fArray.fChildrenSize = 0;
    res->u.fArray.fFirst = NULL;
    res->u.fArray.fLast = NULL;

    return res;
}

struct SResource *string_open(struct SRBRoot *bundle, char *tag, UChar *value, int32_t len, UErrorCode *status) {

    struct SResource *res;

    if(U_FAILURE(*status)) {
        return NULL;
    }

    res = (struct SResource *)uprv_malloc(sizeof(struct SResource));

    if(res == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }

    res->fType = RES_STRING;
    res->fKey = bundle_addtag(bundle, tag, status);

    if(U_FAILURE(*status)) {
        uprv_free(res);
        return NULL;
    }

    res->fNext = NULL;

    res->u.fString.fLength = len;
    res->u.fString.fChars = (UChar *)uprv_malloc(sizeof(UChar) * (len+1));
    if(res->u.fString.fChars == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        uprv_free(res);
        return NULL;
    }
    uprv_memcpy(res->u.fString.fChars, value, sizeof(UChar) * (len+1));
    res->fSize = sizeof(int32_t) + sizeof(UChar) * (len+1);

    return res;
}

struct SResource* intvector_open(struct SRBRoot *bundle, char *tag, UErrorCode *status) {
    struct SResource *res;

    if(U_FAILURE(*status)) {
        return NULL;
    }

    res = (struct SResource *)uprv_malloc(sizeof(struct SResource));

    if(res == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }

    res->fType = RES_ARRAY;
    res->fKey = bundle_addtag(bundle, tag, status);

    if(U_FAILURE(*status)) {
        uprv_free(res);
        return NULL;
    }

    res->fNext = NULL;
    res->fSize = sizeof(int32_t);
    res->u.fIntVector.fCount = 0;
    res->u.fIntVector.fArray = (uint32_t *)uprv_malloc(sizeof(uint32_t) * RESLIST_MAX_INT_VECTOR);
    if(res->u.fIntVector.fArray == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        uprv_free(res);
        return NULL;
    }

    return res;
}

struct SResource *int_open(struct SRBRoot *bundle, char *tag, int32_t value, UErrorCode *status) {

    struct SResource *res;

    if(U_FAILURE(*status)) {
        return NULL;
    }

    res = (struct SResource *)uprv_malloc(sizeof(struct SResource));

    if(res == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }

    res->fType = RES_INT;
    res->fKey = bundle_addtag(bundle, tag, status);

    if(U_FAILURE(*status)) {
        uprv_free(res);
        return NULL;
    }

    res->fSize = 0;
    res->fNext = NULL;
    res->u.fIntValue.fValue = value;

    return res;
}

struct SResource *bin_open(struct SRBRoot *bundle, const char *tag, uint32_t length, uint8_t *data, UErrorCode *status) {

    struct SResource *res;

    if(U_FAILURE(*status)) {
        return NULL;
    }

    res = (struct SResource *)uprv_malloc(sizeof(struct SResource));

    if(res == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }

    res->fType = RES_BINARY;
    res->fKey = bundle_addtag(bundle, tag, status);

    if(U_FAILURE(*status)) {
        uprv_free(res);
        return NULL;
    }

    res->fNext = NULL;

    res->u.fBinaryValue.fLength = length;
    res->u.fBinaryValue.fData = (uint8_t *)uprv_malloc(sizeof(uint8_t) * length);
    if(res->u.fString.fChars == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        uprv_free(res);
        return NULL;
    }
    uprv_memcpy(res->u.fBinaryValue.fData, data, length);

    res->fSize = sizeof(int32_t) + sizeof(uint8_t) * length + BIN_ALIGNMENT;

    return res;
}

struct SRBRoot *bundle_open(UErrorCode *status) {
    struct SRBRoot *bundle = NULL;

    if(U_FAILURE(*status)) {
        return NULL;
    }

    bundle = (struct SRBRoot*) uprv_malloc(sizeof(struct SRBRoot));
    if(bundle == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return 0;
    }

    bundle->fLocale = NULL;
    bundle->fKeyPoint = 0;
    bundle->fKeys = (char *) uprv_malloc(sizeof(char) * KEY_SPACE_SIZE);
    if(bundle->fKeys == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        uprv_free(bundle);
        return NULL;
    }
    bundle->fCount = 0;
    bundle->fRoot = table_open(bundle, NULL, status);
    if((bundle->fRoot == NULL) || (U_FAILURE(*status))) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        uprv_free(bundle->fKeys);
        uprv_free(bundle);
        return NULL;
    }
/*
    bundle->fRoot = (struct SResource*) uprv_malloc(sizeof(struct SResource));
    if(bundle->fRoot == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        uprv_free(bundle->fKeys);
        uprv_free(bundle);
        return NULL;
    }
    bundle->fRoot->fType = RES_TABLE;
    bundle->fRoot->fSize = sizeof(uint16_t);
    bundle->fRoot->u.fTable.fCount = 0;
    bundle->fRoot->u.fTable.fFirst = NULL;
    bundle->fRoot->u.fTable.fRoot = bundle;
*/
    return bundle;
}

/* Closing Functions */

void table_close(struct SResource *table, UErrorCode *status) {
    struct SResource *current = NULL;
    struct SResource *prev = NULL;

    current = table->u.fTable.fFirst;

    while(current!=NULL) {
        prev = current;
        current = current->fNext;
        res_close(prev, status);
    }
}

void array_close(struct SResource *array, UErrorCode *status) {
    struct SResource *current = NULL;
    struct SResource *prev = NULL;

    current = array->u.fArray.fFirst;

    while(current!=NULL) {
        prev = current;
        current = current->fNext;
        res_close(prev, status);
    }

}

void string_close(struct SResource *string, UErrorCode *status) {
    if(string->u.fString.fChars != NULL) {
        uprv_free(string->u.fString.fChars);
    }
}

void intvector_close(struct SResource *intvector, UErrorCode *status) {
    if(intvector->u.fIntVector.fArray != NULL) {
        uprv_free(intvector->u.fIntVector.fArray);
    }
}

void int_close(struct SResource *intres, UErrorCode *status) {
    /* Intentionally left blank */
}

void bin_close(struct SResource *binres, UErrorCode *status) {
    if(binres->u.fBinaryValue.fData != NULL) {
        uprv_free(binres->u.fBinaryValue.fData);
    }
}

void res_close(struct SResource *res, UErrorCode *status) {
    if(res != NULL) {
        switch(res->fType) {
        case RES_STRING:
            string_close(res, status);
            break;
        case RES_INT_VECTOR:
            intvector_close(res, status);
            break;
        case RES_BINARY:
            bin_close(res, status);
            break;
        case RES_INT:
            int_close(res, status);
            break;
        case RES_ARRAY:
            array_close(res, status);
            break;
        case RES_TABLE : 
            table_close(res, status);
            break;
        default:
            /* Shouldn't happen */
            break;
        }

        uprv_free(res);
    }

}

void bundle_close(struct SRBRoot *bundle, UErrorCode *status) {
    struct SResource *current = NULL;
    struct SResource *prev = NULL;

    if(bundle->fRoot!=NULL) {
        current = bundle->fRoot->u.fTable.fFirst;

        while(current!=NULL) {
            prev = current;
            current = current->fNext;
            res_close(prev, status);
        }


        uprv_free(bundle->fRoot);
    }

    if(bundle->fLocale != NULL) {
        uprv_free(bundle->fLocale);
    }

    if(bundle->fKeys != NULL) {
        uprv_free(bundle->fKeys);
    }

    uprv_free(bundle);
}

/* Adding Functions */

void table_add(struct SResource *table, struct SResource *res, UErrorCode *status) {
    struct SResource *current = NULL;
    struct SResource *prev = NULL;
    struct SResTable *list;

    if(U_FAILURE(*status)) {
        return;
    }

    /* here we need to traverse the list */  
    list = &(table->u.fTable);

    ++(list->fCount);
    table->fSize += sizeof(uint32_t) + sizeof(uint16_t);

    table->u.fTable.fChildrenSize += res->fSize + calcPadding(res->fSize);

    if(res->fType == RES_TABLE) {
        table->u.fTable.fChildrenSize += res->u.fTable.fChildrenSize;
    } else if (res->fType == RES_ARRAY) {
        table->u.fTable.fChildrenSize += res->u.fArray.fChildrenSize;
    }

    /* is list still empty? */
    if(list->fFirst == NULL) {
        list->fFirst = res;
        res->fNext = NULL;
        return;
    } else {
        current = list->fFirst;
    }

    while(current != NULL) {
        if(uprv_strcmp(((list->fRoot->fKeys)+(current->fKey)), ((list->fRoot->fKeys)+(res->fKey)))<0) {
            prev = current;
            current = current->fNext;
        } else if (uprv_strcmp(((list->fRoot->fKeys)+(current->fKey)), ((list->fRoot->fKeys)+(res->fKey)))>0) { /*we're either in front of list, or in middle*/
            if(prev == NULL) { /*front of the list*/
                list->fFirst = res;
            } else { /*middle of the list*/
                prev->fNext = res;
            }
            res->fNext = current;
            return;
        } else { /* Key already exists! ERROR! */
            char msg[100]={ "duplicate key '" };
            uprv_strcat(msg, (list->fRoot->fKeys)+(current->fKey));
            uprv_strcat(msg, "' in table");
            setErrorText(msg);
            *status = U_UNSUPPORTED_ERROR;
            return;
        }
    }

    /* end of list */
    prev->fNext = res;
    res->fNext = NULL;
}

void array_add(struct SResource *array, struct SResource *res, UErrorCode *status) {

    if(U_FAILURE(*status)) {
        return;
    }

    if(array->u.fArray.fFirst == NULL) {
        array->u.fArray.fFirst = res;
        array->u.fArray.fLast = res;
    } else {
        array->u.fArray.fLast->fNext = res;
        array->u.fArray.fLast = res;
    }
    (array->u.fArray.fCount)++;

    array->fSize += sizeof(uint32_t);
    array->u.fArray.fChildrenSize += res->fSize + calcPadding(res->fSize);

    if(res->fType == RES_TABLE) {
        array->u.fArray.fChildrenSize += res->u.fTable.fChildrenSize;
    } else if (res->fType == RES_ARRAY) {
        array->u.fArray.fChildrenSize += res->u.fArray.fChildrenSize;
    }
}

void intvector_add(struct SResource *intvector, int32_t value, UErrorCode *status) {

    if(U_FAILURE(*status)) {
        return;
    }

    *(intvector->u.fIntVector.fArray+(intvector->u.fIntVector.fCount)) = value;

    (intvector->u.fIntVector.fCount)++;

    intvector->fSize += sizeof(uint32_t);

}

/* Misc Functions */

void bundle_setlocale(struct SRBRoot *bundle, UChar *locale, UErrorCode *status) {

    if(U_FAILURE(*status)) {
        return;
    }

    if (bundle->fLocale!=NULL) {
        uprv_free(bundle->fLocale);
    }

    bundle->fLocale= (char*) uprv_malloc(sizeof(char) * (u_strlen(locale)+1));

    if(bundle->fLocale == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }

    /*u_strcpy(bundle->fLocale, locale);*/
    u_UCharsToChars(locale, bundle->fLocale, u_strlen(locale)+1);

}

uint16_t bundle_addtag(struct SRBRoot *bundle, const char *tag, UErrorCode *status) {
    uint16_t keypos;

    if(U_FAILURE(*status)) {
        return (uint16_t)-1;
    }

    if(tag == NULL) {
        return (uint16_t)-1;
    }

    keypos = bundle->fKeyPoint;

    bundle->fKeyPoint += (uint16_t)(uprv_strlen(tag)+1);

    if(bundle->fKeyPoint > KEY_SPACE_SIZE) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return (uint16_t)-1;
    }

    uprv_strcpy((bundle->fKeys)+keypos, tag);

    return keypos;
}

struct SResource *table_get(struct SResource *table, char *key, UErrorCode *status) {
    return NULL;
}
