/*
*******************************************************************************
*
*   © 2016 and later: Unicode, Inc. and others.
*   License & terms of use: http://www.unicode.org/copyright.html#License
*
*******************************************************************************
*******************************************************************************
*
*   Copyright (C) 1999-2007, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*   file name:  uresb.c
*   encoding:   UTF-8
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 2000sep6
*   created by: Vladimir Weinstein
*/

/******************************************************************************
 * This program prints out resource bundles - example for
 * ICU workshop
 * TODO: make a complete i18n layout for this program.
 ******************************************************************************/

#include "unicode/putil.h"
#include "unicode/ures.h"
#include "unicode/ustdio.h"
#include "unicode/uloc.h"
#include "unicode/ustring.h"
#include "uoptions.h"
#include "toolutil.h"

#include <string.h>
#include <stdlib.h>
#ifdef WIN32
#include <direct.h>
#else
#include <unistd.h>
#endif

#define URESB_DEFAULTTRUNC 40

static char *currdir = NULL;
/*--locale sr_YU and --encoding cp855
 * are interesting on Win32
 */

static const char *locale = NULL;
static const char *encoding = NULL;
static const char *resPath = NULL;
static const int32_t indentsize = 4;
static UFILE *outerr = NULL;
static int32_t truncsize = URESB_DEFAULTTRUNC;
static UBool trunc = FALSE;

const UChar baderror[] = { 0x0042, 0x0041, 0x0044, 0x0000 };

const UChar *getErrorName(UErrorCode errorNumber);
void reportError(UErrorCode *status);
static UChar *quotedString(const UChar *string);
void printOutBundle(UFILE *out, UResourceBundle *resource, int32_t indent, UErrorCode *status);
void printIndent(UFILE *out, int32_t indent);
void printHex(UFILE *out, const int8_t *what);

static UOption options[]={
    UOPTION_HELP_H,
    UOPTION_HELP_QUESTION_MARK,
    { "locale", NULL, NULL, NULL, 'l', UOPT_REQUIRES_ARG, 0 },
    UOPTION_ENCODING,
    { "path", NULL, NULL, NULL, 'p', UOPT_OPTIONAL_ARG, 0 },
    { "truncate", NULL, NULL, NULL, 't', UOPT_OPTIONAL_ARG, 0 },
    UOPTION_VERBOSE
};

static UBool VERBOSE = FALSE;

extern int
main(int argc, char* argv[]) {

    UResourceBundle *bundle = NULL;
    UErrorCode status = U_ZERO_ERROR;
    UFILE *out = NULL;
    int32_t i = 0;
    const char* arg;
    char resPathBuffer[1024];
#ifdef WIN32
    currdir = _getcwd(NULL, 0);
#else
    currdir = getcwd(NULL, 0);
#endif

    argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options);

    /* error handling, printing usage message */
    if(argc<0) {
        fprintf(stderr,
            "error in command line argument \"%s\"\n",
            argv[-argc]);
    }
    if(argc<2 || options[0].doesOccur || options[1].doesOccur) {
        fprintf(stderr,
            "usage: %s [-options] locale(s)\n",
            argv[0]);
        return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
    }

    if(options[2].doesOccur) {
        locale = options[2].value;
    } else {
        locale = 0;
    }

    if(options[3].doesOccur) {
        encoding = options[3].value;
    } else {
        encoding = NULL;
    }

    if(options[4].doesOccur) {
        if(options[4].value != NULL) {
            resPath = options[4].value; /* we'll use users resources */
        } else {
            resPath = NULL; /* we'll use ICU system resources for dumping */
        }
    } else {
        strcpy(resPathBuffer, currdir);
        /*strcat(resPathBuffer, U_FILE_SEP_STRING);
        strcat(resPathBuffer, "uresb");*/
        resPath = resPathBuffer; /* we'll just dump uresb samples resources */
    }

    if(options[5].doesOccur) {
        trunc = TRUE;
        if(options[5].value != NULL) {
            truncsize = atoi(options[5].value); /* user defined printable size */
        } else {
            truncsize = URESB_DEFAULTTRUNC; /* we'll use default omitting size */
        }
    } else {
        trunc = FALSE;
    }

    if(options[6].doesOccur) {
        VERBOSE = TRUE;
    }

    outerr = u_finit(stderr, locale, encoding);
    out = u_finit(stdout, locale, encoding); 

    for(i = 1; i < argc; ++i) {
        status = U_ZERO_ERROR;
        arg = getLongPathname(argv[i]);

        u_fprintf(out, "uresb: processing file \"%s\" in path \"%s\"\n", arg, resPath);
        bundle = ures_open(resPath, arg, &status);
        if(U_SUCCESS(status)) {
            u_fprintf(out, "%s\n", arg);
            printOutBundle(out, bundle, 0, &status);
        } else {
            reportError(&status);
        }

        ures_close(bundle);
    }



    u_fclose(out);
    u_fclose(outerr);
    return 0;
}

void printIndent(UFILE *out, int32_t indent) {
    char inchar[256];
    int32_t i = 0;
    for(i = 0; i<indent; i++) {
        inchar[i] = ' ';
    }
    inchar[indent] = '\0';
    u_fprintf(out, "%s", inchar);
}

void printHex(UFILE *out, const int8_t *what) {
  u_fprintf(out, "%02X", (uint8_t)*what);
}

static UChar *quotedString(const UChar *string) {
    int len = u_strlen(string);
    int alen = len;
    const UChar *sp;
    UChar *newstr, *np;

    for (sp = string; *sp; ++sp) {
        switch (*sp) {
            case '\n':
            case 0x0022:
                ++alen;
                break;
        }
    }

    newstr = (UChar *) malloc((1 + alen) * sizeof(*newstr));
    for (sp = string, np = newstr; *sp; ++sp) {
        switch (*sp) {
            case '\n':
                *np++ = 0x005C;
                *np++ = 0x006E;
                break;

            case 0x0022:
                *np++ = 0x005C;
                
            default:
                *np++ = *sp;
                break;
        }
    }
    *np = 0;

    return newstr;
}

void printOutBundle(UFILE *out, UResourceBundle *resource, int32_t indent, UErrorCode *status) {
    int32_t i = 0;
    const char *key = ures_getKey(resource);

    switch(ures_getType(resource)) {
    case URES_STRING :
        {
            int32_t len=0;
            const UChar*thestr = ures_getString(resource, &len, status);
            UChar *string = quotedString(thestr);

            /* TODO: String truncation */
            /*
            if(trunc && len > truncsize) {
                printIndent(out, indent);
                u_fprintf(out, "// WARNING: this string, size %d is truncated to %d\n", len, truncsize/2);
                len = truncsize/2;
            }
            */
            printIndent(out, indent);
            if(key != NULL) {
                u_fprintf(out, "%s { \"%S\" } ", key, string);
            } else {
                u_fprintf(out, "\"%S\",", string);
            }
            if(VERBOSE) {
                u_fprintf(out, " // STRING");
            }
            u_fprintf(out, "\n");
            free(string);
        }
        break;
    case URES_INT :
        printIndent(out, indent);
        if(key != NULL) {
            u_fprintf(out, "%s", key);
        }
        u_fprintf(out, ":int { %li } ", ures_getInt(resource, status));
        
        if(VERBOSE) {
            u_fprintf(out, " // INT");
        }
        u_fprintf(out, "\n");
        break;
    case URES_BINARY :
        {
            int32_t len = 0;
            const int8_t *data = (const int8_t *)ures_getBinary(resource, &len, status);
            if(trunc && len > truncsize) {
                printIndent(out, indent);
                u_fprintf(out, "// WARNING: this resource, size %li is truncated to %li\n", len, truncsize/2);
                len = truncsize/2;
            }
            if(U_SUCCESS(*status)) {
                printIndent(out, indent);
                if(key != NULL) {
                    u_fprintf(out, "%s", key);
                }
                u_fprintf(out, ":binary { ");
                for(i = 0; i<len; i++) {
                    printHex(out, data++);
                }
                u_fprintf(out, " }");
                if(VERBOSE) {
                    u_fprintf(out, " // BINARY");
                }
                u_fprintf(out, "\n");
                
            } else {
                reportError(status);
            }
        }
        break;
    case URES_INT_VECTOR :
      {
          int32_t len = 0;
          const int32_t *data = ures_getIntVector(resource, &len, status);
          if(U_SUCCESS(*status)) {
              printIndent(out, indent);
              if(key != NULL) {
                  u_fprintf(out, "%s", key);
              } 
              u_fprintf(out, ":intvector { ");
              for(i = 0; i<len-1; i++) {
                  u_fprintf(out, "%d, ", data[i]);
              }
              if(len > 0) {
                  u_fprintf(out, "%d ", data[len-1]);
              }
              u_fprintf(out, "}");
              if(VERBOSE) {
                  u_fprintf(out, " // INTVECTOR");
              }
              u_fprintf(out, "\n");
              
          } else {
              reportError(status);
          }
      }
      break;
    case URES_TABLE :
    case URES_ARRAY :
        {
            UResourceBundle *t = NULL;
            ures_resetIterator(resource);
            printIndent(out, indent);
            if(key != NULL) {
                u_fprintf(out, "%s ", key);
            }
            u_fprintf(out, "{");
            if(VERBOSE) {
                if(ures_getType(resource) == URES_TABLE) {
                    u_fprintf(out, " // TABLE");
                } else {
                    u_fprintf(out, " // ARRAY");
                }
            }
            u_fprintf(out, "\n");

            while(ures_hasNext(resource)) {
                t = ures_getNextResource(resource, t, status);
                printOutBundle(out, t, indent+indentsize, status);
            }

            printIndent(out, indent);
            u_fprintf(out, "}\n");
            ures_close(t);
        }
        break;
    default:
        break;
    }

}

void reportError(UErrorCode *status) {
    u_fprintf(outerr, "Error %d(%s) : %U happened!\n", *status, u_errorName(*status), getErrorName(*status));
}


const UChar *getErrorName(UErrorCode errorNumber) {
    UErrorCode status = U_ZERO_ERROR;
    int32_t len = 0;

    UResourceBundle *error = ures_open(currdir, locale, &status);

    UResourceBundle *errorcodes = ures_getByKey(error, "errorcodes", NULL, &status);

    const UChar *result = ures_getStringByIndex(errorcodes, errorNumber, &len, &status);

    ures_close(errorcodes);
    ures_close(error);

    if(U_SUCCESS(status)) {
        return result;
    } else {
        return baderror;
    }

}
