/*
*******************************************************************************
*
*   Copyright (C) 1999-2010, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*   file name:  gentest.c
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 2000mar03
*   created by: Madhu Katragadda
*
*   This program writes a little data file for testing the udata API.
*/

#include <stdio.h>
#include <stdlib.h>
#include "unicode/utypes.h"
#include "unicode/putil.h"
#include "unicode/uclean.h"
#include "unicode/udata.h"
#include "unicode/udbgutil.h"
#include "unewdata.h"
#include "cmemory.h"
#include "cstring.h"
#include "uoptions.h"
#include "gentest.h"
#include "toolutil.h"

#define DATA_NAME "test"
#define DATA_TYPE "icu"

/* UDataInfo cf. udata.h */
static const UDataInfo dataInfo={
    sizeof(UDataInfo),
    0,

    U_IS_BIG_ENDIAN,
    U_CHARSET_FAMILY,
    sizeof(UChar),
    0,

    {0x54, 0x65, 0x73, 0x74},     /* dataFormat="Test" */
    {1, 0, 0, 0},                 /* formatVersion */
    {1, 0, 0, 0}                  /* dataVersion */
};

static void createData(const char*, UErrorCode *);

static int outputJavaStuff(const char * progname, const char *outputDir);

static UOption options[]={
  /*0*/ UOPTION_HELP_H,
  /*1*/ UOPTION_HELP_QUESTION_MARK,
  /*2*/ UOPTION_DESTDIR,
  /*3*/ UOPTION_DEF("genres", 'r', UOPT_NO_ARG),
  /*4*/ UOPTION_DEF("javastuff", 'j', UOPT_NO_ARG),  
};

extern int
main(int argc, char* argv[]) {
    UErrorCode errorCode = U_ZERO_ERROR;

    /* preset then read command line options */
    options[2].value=u_getDataDirectory();
    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<0 || options[0].doesOccur || options[1].doesOccur) {
        fprintf(stderr,
            "usage: %s [-options]\n"
            "\tcreate the test file " DATA_NAME "." DATA_TYPE " unless the -r option is given.\n"
            "\toptions:\n"
            "\t\t-h or -? or --help  this usage text\n"
            "\t\t-d or --destdir     destination directory, followed by the path\n"
            "\t\t-r or --genres      generate resource file testtable32.txt instead of UData test \n"
            "\t\t-j or --javastuff   generate Java source for DebugUtilities. \n",
            argv[0]);
        return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
    }

    if( options[4].doesOccur ) {
    	return outputJavaStuff( argv[0], options[2].value );
    } else if ( options[3].doesOccur ) {
        return genres32( argv[0], options[2].value );
    } else { 
        /* printf("Generating the test memory mapped file\n"); */
        createData(options[2].value, &errorCode);
    }
    return U_FAILURE(errorCode);
}

/* Create data file ----------------------------------------------------- */
static void
createData(const char* outputDirectory, UErrorCode *errorCode) {
    UNewDataMemory *pData;
    char stringValue[]={'Y', 'E', 'A', 'R', '\0'};
    uint16_t intValue=2000;

    long dataLength;
    uint32_t size;

    pData=udata_create(outputDirectory, DATA_TYPE, DATA_NAME, &dataInfo,
                       U_COPYRIGHT_STRING, errorCode);
    if(U_FAILURE(*errorCode)) {
        fprintf(stderr, "gentest: unable to create data memory, %s\n", u_errorName(*errorCode));
        exit(*errorCode);
    }

    /* write the data to the file */
    /* a 16 bit value  and a String*/
    udata_write16(pData, intValue);
    udata_writeString(pData, stringValue, sizeof(stringValue));

    /* finish up */
    dataLength=udata_finish(pData, errorCode);
    if(U_FAILURE(*errorCode)) {
        fprintf(stderr, "gentest: error %d writing the output file\n", *errorCode);
        exit(*errorCode);
    }
    size=sizeof(stringValue) + sizeof(intValue);


    if(dataLength!=(long)size) {
        fprintf(stderr, "gentest: data length %ld != calculated size %lu\n",
            dataLength, (unsigned long)size);
        exit(U_INTERNAL_PROGRAM_ERROR);
    }
}

/* Create Java file ----------------------------------------------------- */

static int
outputJavaStuff(const char* progname, const char *outputDir) {
    int32_t i,t,count;
    char file[512];
    FILE *out;
    int32_t year = getCurrentYear();

    uprv_strcpy(file,outputDir);
    if(*outputDir &&  /* don't put a trailing slash if outputDir is empty */ 
        file[strlen(file)-1]!=U_FILE_SEP_CHAR) {
            uprv_strcat(file,U_FILE_SEP_STRING);
    }
    uprv_strcat(file,"DebugUtilitiesData.java");
    out = fopen(file, "w");
    /*puts(file);*/
    printf("%s: Generating %s\n", progname, file);
    if(out == NULL) {
        fprintf(stderr, "%s: Couldn't create resource test file %s\n",
            progname, file);
        return 1;
    }

    fprintf(out, "/** Copyright (C) 2007-%d, International Business Machines Corporation and Others. All Rights Reserved. **/\n\n", year);
    fprintf(out, "/* NOTE: this file is AUTOMATICALLY GENERATED by gentest.\n"
                 " * See: {ICU4C}/source/data/icu4j-readme.txt for more information. \n"
                 " **/\n\n");
    fprintf(out, "package com.ibm.icu.dev.test.util;\n\n");
    fprintf(out, "public class DebugUtilitiesData extends Object {\n");
    fprintf(out, "    public static final String ICU4C_VERSION=\"%s\";\n", U_ICU_VERSION);
    for(t=0;t<UDBG_ENUM_COUNT;t++) {
        fprintf(out, "    public static final int %s = %d;\n", udbg_enumName(UDBG_UDebugEnumType,t), t);
    }
    fprintf(out, "    public static final String [] TYPES = { \n");
    for(t=0;t<UDBG_ENUM_COUNT;t++) {
        fprintf(out, "        \"%s\", /* %d */\n", udbg_enumName(UDBG_UDebugEnumType,t), t);
    }
    fprintf(out, "    };\n\n");

    fprintf(out, "    public static final String [][] NAMES = { \n");
    for(t=0;t<UDBG_ENUM_COUNT;t++) {
        count = udbg_enumCount((UDebugEnumType)t);
        fprintf(out, "        /* %s, %d */\n", udbg_enumName(UDBG_UDebugEnumType,t), t);
        fprintf(out, "        { \n");
        for(i=0;i<count;i++) {
            fprintf(out, 
                "           \"%s\", /* %d */ \n", udbg_enumName((UDebugEnumType)t,i), i);
        }
        fprintf(out, "        },\n");
    }
    fprintf(out, "    };\n\n");

    fprintf(out, "    public static final int [][] VALUES = { \n");
    for(t=0;t<UDBG_ENUM_COUNT;t++) {
        count = udbg_enumCount((UDebugEnumType)t);
        fprintf(out, "        /* %s, %d */\n", udbg_enumName(UDBG_UDebugEnumType,t), t);
        fprintf(out, "        { \n");
        for(i=0;i<count;i++) {
            fprintf(out, 
                "           ");
            switch(t) {
#if !UCONFIG_NO_FORMATTING
            case UDBG_UCalendarDateFields:
            case UDBG_UCalendarMonths:
                /* Temporary workaround for IS_LEAP_MONTH #6051 */
                if (t == UDBG_UCalendarDateFields && i == 22) {
                  fprintf(out, "com.ibm.icu.util.ChineseCalendar.%s, /* %d */", udbg_enumName((UDebugEnumType)t,i), i);
                } else {
                  fprintf(out, "com.ibm.icu.util.Calendar.%s, /* %d */", udbg_enumName((UDebugEnumType)t,i), i);
                }
                break;
#endif
            case UDBG_UDebugEnumType:
            default:
                fprintf(out,"%d, /* %s */", i, udbg_enumName((UDebugEnumType)t,i));
            }
            fprintf(out,"\n");
        }
        fprintf(out, "        },\n");
    }
    fprintf(out, "    };\n\n");
    fprintf(out, "}\n");

    fclose(out);

    return 0;

}
