/*
*******************************************************************************
*
*   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 <assert.h>
#include "reslist.h"
#include "unewdata.h"
#include "unicode/ures.h"
#include "error.h"

#define BIN_ALIGNMENT 16

static UBool gIncludeCopyright = FALSE;

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);

}

void setIncludeCopyright(UBool val){
    gIncludeCopyright=val;
}

/* 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 *resources = NULL;
    uint32_t  i         = 0;

    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 {
        /* array is empty */
        udata_write32(mem, 0);
    }

    return usedOffset;
}

static uint32_t intvector_write(UNewDataMemory *mem, struct SResource *res,
                                uint32_t usedOffset, UErrorCode *status) {
  uint32_t i = 0;
    udata_write32(mem, res->u.fIntVector.fCount);
    for(i = 0; i<res->u.fIntVector.fCount; i++) {
      udata_write32(mem, res->u.fIntVector.fArray[i]);
    }

    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);
    if (res->u.fBinaryValue.fLength > 0) {
        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) {
            assert(i < res->u.fTable.fCount);

            /* where the key is plus root pointer */
            keys[i] = (uint16_t) (current->fKey + sizeof(uint32_t));

            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);
        case RES_INT_VECTOR:
            return intvector_write (mem, res, usedOffset, status);
        case RES_BINARY:
            return bin_write       (mem, res, usedOffset, status);
        case RES_INT:
            return int_write       (mem, res, usedOffset, status);
        case RES_ARRAY:
            return array_write     (mem, res, usedOffset, status);
        case RES_TABLE:
            return table_write     (mem, res, usedOffset, status);

        default:
            break;
        }
    }

    *status = U_INTERNAL_PROGRAM_ERROR;
    return 0;
}

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, (gIncludeCopyright==TRUE)? U_COPYRIGHT_STRING:NULL, 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_INT_VECTOR;
    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;
    if (length > 0) {
        res->u.fBinaryValue.fData   = (uint8_t *) uprv_malloc(sizeof(uint8_t) * length);

        if (res->u.fBinaryValue.fData == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            uprv_free(res);
            return NULL;
        }

        uprv_memcpy(res->u.fBinaryValue.fData, data, length);
    }
    else {
        res->u.fBinaryValue.fData = NULL;
    }

    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;
    }

    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, int linenumber, UErrorCode *status) {
    struct SResource *current = NULL;
    struct SResource *prev    = NULL;
    struct SResTable *list;

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

    /* remember this linenumber to report to the user if there is a duplicate key */
    res->line = linenumber;

    /* 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;
    }

    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! */
            error(linenumber, "duplicate key '%s' in table, first appeared at line %d", list->fRoot->fKeys + current->fKey, current->line);
            *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;
}
