/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 1997-2001, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/
/********************************************************************************
*
* File CDTRGTST.C
*
*     Madhu Katragadda            Ported for C API
* Modification History:
*   Date        Name        Description
*   07/15/99    helena      Ported to HPUX 10/11 CC.
*********************************************************************************
*/
/* REGRESSION TEST FOR DATE FORMAT */

#include "unicode/uloc.h"
#include "unicode/utypes.h"
#include "unicode/udat.h"
#include "unicode/ucal.h"
#include "unicode/unum.h"
#include "unicode/ustring.h"
#include "cintltst.h"
#include "cdtrgtst.h"
#include "cmemory.h"

void addDateForRgrTest(TestNode** root);

void addDateForRgrTest(TestNode** root)
{
    addTest(root, &Test4029195, "tsformat/cdtrgtst/Test4029195");
    addTest(root, &Test4056591, "tsformat/cdtrgtst/Test4056591");
    addTest(root, &Test4059917, "tsformat/cdtrgtst/Test4059917");
    addTest(root, &Test4060212, "tsformat/cdtrgtst/Test4060212");
    addTest(root, &Test4061287, "tsformat/cdtrgtst/Test4061287");
    addTest(root, &Test4073003, "tsformat/cdtrgtst/Test4073003");
    addTest(root, &Test4162071, "tsformat/cdtrgtst/Test4162071");
    addTest(root, &Test714,   "tsformat/cdtrgtst/Test714");
}

/**
 * @bug 4029195
 */
void Test4029195() 
{
    int32_t resultlength, resultlengthneeded;
    UChar  *fmdt, *todayS, *rt;
    UChar *pat=NULL;
    UChar *temp;
    UDate today, d1;
    UDateFormat *df;
    int32_t parsepos;
    UErrorCode status = U_ZERO_ERROR;

    log_verbose("Testing date format and parse function in regression test\n");
    today = ucal_getNow();
    
    df = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,"en_US", NULL, 0, &status);
    if(U_FAILURE(status))
    {
        log_err("FAIL: error in creating the dateformat using default date and time style : %s\n", myErrorName(status));
    }
    resultlength=0;
    resultlengthneeded=udat_toPattern(df, TRUE, NULL, resultlength, &status);
    if(status==U_BUFFER_OVERFLOW_ERROR)
    {
        status=U_ZERO_ERROR;
        resultlength=resultlengthneeded + 1;
        pat=(UChar*)uprv_malloc(sizeof(UChar) * resultlength);
        udat_toPattern(df, TRUE, pat, resultlength, &status);
    }
    
    log_verbose("pattern: %s\n", austrdup(pat));

    
    fmdt = myFormatit(df, today);
    log_verbose("today: %s\n", austrdup(fmdt));
    
    temp=(UChar*)uprv_malloc(sizeof(UChar) * 10);
    u_uastrcpy(temp, "M yyyy dd");
    udat_applyPattern(df, TRUE, temp, u_strlen(temp));
    
    todayS =myFormatit(df, today);
    log_verbose("After teh pattern is applied\n today: %s\n", austrdup(todayS) );
    parsepos=0;
    d1=udat_parse(df, todayS, u_strlen(todayS), &parsepos, &status);
    if(U_FAILURE(status))
    {
        log_err("FAIL: Error in parsing using udat_parse(.....): %s\n", myErrorName(status));
    }
            
    rt =myFormatit(df, d1);
    log_verbose("today: %s\n", austrdup(rt) );
     
    log_verbose("round trip: %s\n", austrdup(rt) );
      
    if(u_strcmp(rt, todayS)!=0) {
            log_err("Fail: Want  %s  Got  %s\n", austrdup(todayS), austrdup(rt) );
    }
    else
        log_verbose("Pass: parse and format working fine\n");
    udat_close(df);
    uprv_free(temp);
    if(pat != NULL) {
        uprv_free(pat);
    }
}


/**
 * @bug 4056591
 * Verify the function of the [s|g]et2DigitYearStart() API.
 */
void Test4056591() 
{
    int i;
    UCalendar *cal;
    UDateFormat *def;    
    UDate start,exp,got;
    UChar s[10];
    UChar *gotdate, *expdate;
    UChar pat[10];
    UChar *tzID;
    UDate d[4];
    UErrorCode status = U_ZERO_ERROR;
    const char* strings[] = {
             "091225",
             "091224",
             "611226",
             "991227"
        };

    log_verbose("Testing s[get] 2 digit year start regressively\n");
    tzID=(UChar*)uprv_malloc(sizeof(UChar) * 4);
    u_uastrcpy(tzID, "PST");
    cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_GREGORIAN, &status);
    if(U_FAILURE(status)){
        log_err("error in ucal_open caldef : %s\n", myErrorName(status));
    }
    ucal_setDateTime(cal, 1809, UCAL_DECEMBER, 25, 17, 40, 30, &status);
    d[0]=ucal_getMillis(cal, &status);
    if(U_FAILURE(status)){
            log_err("Error: failure in get millis: %s\n", myErrorName(status));
    }
    ucal_setDateTime(cal, 1909, UCAL_DECEMBER, 24, 17, 40, 30, &status);
    d[1]=ucal_getMillis(cal, &status);
    ucal_setDateTime(cal, 1861, UCAL_DECEMBER, 26, 17, 40, 30, &status);
    d[2]=ucal_getMillis(cal, &status);
    ucal_setDateTime(cal, 1999, UCAL_DECEMBER, 27, 17, 40, 30, &status);
    d[3]=ucal_getMillis(cal, &status);

    
    u_uastrcpy(pat, "yyMMdd");
    def = udat_openPattern(pat, u_strlen(pat), NULL, &status);
    if(U_FAILURE(status))
    {
        log_err("FAIL: error in creating the dateformat using u_openPattern(): %s\n", myErrorName(status));
    }
    start = 1800;
    udat_set2DigitYearStart(def, start, &status);
    if(U_FAILURE(status))
        log_err("ERROR: in setTwoDigitStartDate: %s\n", myErrorName(status));
    if( (udat_get2DigitYearStart(def, &status) != start))
            log_err("ERROR: get2DigitYearStart broken\n");
        

        for(i = 0; i < 4; ++i) {
            u_uastrcpy(s, strings[i]);
            exp = d[i];
            got = udat_parse(def, s, u_strlen(s), 0, &status);
            gotdate=myFormatit(def, got);
            expdate=myFormatit(def, exp);
            
            if(u_strcmp(gotdate, expdate) !=0){
                log_err("set2DigitYearStart broken for %s \n  got: %s, expected: %s\n", austrdup(s),
                    austrdup(gotdate), austrdup(expdate) );
            }
        }

        udat_close(def);
        ucal_close(cal);
        uprv_free(tzID);
   

}


/**
 * @bug 4059917
 */
void Test4059917() 
{
    UDateFormat* def;
    UChar *myDate;
    UErrorCode status = U_ZERO_ERROR;
    UChar *pattern;
    log_verbose("Testing apply pattern and to pattern regressively\n");
    pattern=(UChar*)uprv_malloc(sizeof(UChar) * 11);
    u_uastrcpy(pattern, "yyyy/MM/dd");
    log_verbose("%s\n", austrdup(pattern) );
    def = udat_openPattern(pattern, u_strlen(pattern), NULL, &status);
    if(U_FAILURE(status))
    {
        log_err("FAIL: error in creating the dateformat using openPattern: %s\n", myErrorName(status));
    }
    myDate=(UChar*)uprv_malloc(sizeof(UChar) * 11);
    u_uastrcpy(myDate, "1970/01/12");
        
    aux917( def, myDate );
    udat_close(def);
    
    u_uastrcpy(pattern, "yyyyMMdd");
    def = udat_openPattern(pattern, u_strlen(pattern), NULL, &status);
    if(U_FAILURE(status))
    {
        log_err("FAIL: error in creating the dateformat using openPattern: %s\n", myErrorName(status));
    }
    u_uastrcpy(myDate, "19700112");
    aux917( def, myDate );
    udat_close(def);    
    uprv_free(pattern);
    uprv_free(myDate);
    
}

void aux917( UDateFormat *fmt, UChar* str) 
{    
   int32_t resultlength, resultlengthneeded;
   UErrorCode status = U_ZERO_ERROR;
   UChar* formatted=NULL;
   UChar *pat=NULL;
   UDate d1=1000000000.0;
   
    resultlength=0;
    resultlengthneeded=udat_toPattern(fmt, TRUE, NULL, resultlength, &status);
    if(status==U_BUFFER_OVERFLOW_ERROR)
    {
        status=U_ZERO_ERROR;
        resultlength=resultlengthneeded + 1;
        pat=(UChar*)uprv_malloc(sizeof(UChar) * (resultlength));
        udat_toPattern(fmt, TRUE, pat, resultlength, &status);
    }
    if(U_FAILURE(status)){
        log_err("failure in retrieving the pattern: %s\n", myErrorName(status));
    }
    log_verbose("pattern: %s\n", austrdup(pat) );
       
    status = U_ZERO_ERROR;
    formatted = myFormatit(fmt, d1);
    if( u_strcmp(formatted,str)!=0) {
        log_err("Fail: Want %s Got: %s\n", austrdup(str),  austrdup(formatted) );
    }
    uprv_free(pat);
}

/**
 * @bug 4060212
 */
void Test4060212() 
{
    int32_t pos;
    UCalendar *cal;
    UDateFormat *formatter, *fmt;
    UErrorCode status = U_ZERO_ERROR;
    UDate myDate;
    UChar *myString;
    UChar dateString[20], pattern[20], tzID[4];
    u_uastrcpy(dateString, "1995-040.05:01:29");
    u_uastrcpy(pattern, "yyyy-DDD.hh:mm:ss");

    log_verbose( "dateString= %s Using yyyy-DDD.hh:mm:ss\n", austrdup(dateString) );
    status = U_ZERO_ERROR;
    
    formatter = udat_openPattern(pattern, u_strlen(pattern), "en_US", &status);
    pos=0;
    myDate = udat_parse(formatter, dateString, u_strlen(dateString), &pos, &status);
    
    
    fmt = udat_open(UDAT_FULL,UDAT_LONG ,NULL, NULL, 0, &status);
    if(U_FAILURE(status))
    {
        log_err("FAIL: error in creating the dateformat using default date and time style: %s\n", 
                        myErrorName(status) );
    }
    myString = myFormatit(fmt, myDate);
    u_uastrcpy(tzID, "PST");
    cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_GREGORIAN, &status);
    if(U_FAILURE(status)){
        log_err("FAIL: error in ucal_open caldef : %s\n", myErrorName(status));
    }
    ucal_setMillis(cal, myDate, &status);
    if ((ucal_get(cal, UCAL_DAY_OF_YEAR, &status) != 40)){
        log_err("Fail: Got  %d Expected 40\n", ucal_get(cal, UCAL_DAY_OF_YEAR, &status));
    }
    
    udat_close(formatter);
    ucal_close(cal);
    udat_close(fmt);
    
}

/**
 * @bug 4061287
 */
void Test4061287() 
{
    UBool ok;
    int32_t pos;
    UDateFormat *df;
    UErrorCode status = U_ZERO_ERROR;
    UDate myDate;
    UChar pattern[21], dateString[11];
    
    u_uastrcpy(dateString, "35/13/1971");
    u_uastrcpy(pattern, "dd/mm/yyyy");
    status = U_ZERO_ERROR;
    log_verbose("Testing parsing by changing the attribute lenient\n");
    df = udat_openPattern(pattern, u_strlen(pattern), NULL, &status);
    if(U_FAILURE(status)){
        log_err("ERROR: failure in open pattern of test4061287: %s\n", myErrorName(status));
    }

    pos=0;
    
    udat_setLenient(df, FALSE);
       ok=udat_isLenient(df);
    if(ok==TRUE)
        log_err("setLenient nor working\n");
    ok = FALSE;
    myDate = udat_parse(df, dateString, u_strlen(dateString), &pos, &status);
    if(U_FAILURE(status))
        ok = TRUE;
    if(ok!=TRUE) 
        log_err("Fail: Lenient not working: does lenient parsing in spite of setting Leninent as FALSE ");

    udat_close(df);
    
}



/* The java.text.DateFormat.parse(String) method expects for the
  US locale a string formatted according to mm/dd/yy and parses it
  correctly.

  When given a string mm/dd/yyyy it only parses up to the first
  two y's, typically resulting in a date in the year 1919.
  
  Please extend the parsing method(s) to handle strings with
  four-digit year values (probably also applicable to various
  other locales.  */
/**
 * @bug 4073003
 */
void Test4073003() 
{
    int32_t pos,i;
    UDate d,dd;
    UChar *datestr;
    UChar temp[15];
    UErrorCode status = U_ZERO_ERROR;
    UDateFormat *fmt;
    UChar *result, *result2;
    const char* tests [] = { 
                "12/25/61", 
                "12/25/1961", 
                "4/3/1999", 
                "4/3/99" 
        };
    
    fmt= udat_open(UDAT_SHORT,UDAT_SHORT ,NULL, NULL, 0, &status);
    if(U_FAILURE(status))
    {
        log_err("FAIL: error in creating the dateformat using short date and time style: %s\n", 
            myErrorName(status));
    }
    u_uastrcpy(temp, "m/D/yy");
    udat_applyPattern(fmt, TRUE, temp, u_strlen(temp));
    
        for(i= 0; i < 4; i+=2) {
            status=U_ZERO_ERROR;
            datestr=(UChar*)uprv_malloc(sizeof(UChar) * (strlen(tests[i])+1));
            u_uastrcpy(datestr, tests[i]);
            
            pos=0;
            d = udat_parse(fmt, datestr, u_strlen(datestr), &pos, &status);
            if(U_FAILURE(status)){
                log_err("ERROR : in test 4073003: %s\n", myErrorName(status));
            }
            
            uprv_free(datestr);
            datestr=(UChar*)uprv_malloc(sizeof(UChar) * (strlen(tests[i+1])+1));
            u_uastrcpy(datestr, tests[i+1]);
        
            pos=0;
            status=U_ZERO_ERROR;
            dd = udat_parse(fmt, datestr, u_strlen(datestr), &pos, &status);
            if(U_FAILURE(status)){
                log_err("ERROR : in test 4073003: %s\n", myErrorName(status));
            }
            uprv_free(datestr);
            
            result =myFormatit(fmt, d);
            result2 =myFormatit(fmt, dd);
            if (u_strcmp(result, result2)!=0){
                log_err("Fail: %s != %s\n", austrdup(result), austrdup(result2) );
                 }
            else{
            log_verbose("Ok: %s == %s\n", austrdup(result), austrdup(result2) );
            }
            
            
       
        }
        udat_close(fmt);
}

/**
 * @bug 4162071
 **/
void Test4162071() 
{
    int32_t pos;
    UDate x;
    UErrorCode status = U_ZERO_ERROR;
    UDateFormat *df;
    UChar datestr[30];
    UChar format[50];
    u_uastrcpy(datestr, "Thu, 30-Jul-1999 11:51:14 GMT");
    u_uastrcpy(format, "EEE', 'dd-MMM-yyyy HH:mm:ss z"); /*  RFC 822/1123 */
    status = U_ZERO_ERROR;
    /* Can't hardcode the result to assume the default locale is "en_US". */
    df = udat_openPattern(format, u_strlen(format), "en_US", &status);
    if(U_FAILURE(status)){
        log_err("ERROR: couldn't create date format: %s\n", myErrorName(status));
    }
  pos=0;
    x = udat_parse(df, datestr, u_strlen(datestr), &pos, &status);
    if(U_FAILURE(status)){
                log_err("ERROR : parse format  %s failes : %s\n", austrdup(format), myErrorName(status));
            }
    else{
        log_verbose("Parse format \"%s \" ok.\n", austrdup(format) );
    }
    log_verbose("date= %s\n", austrdup(myFormatit(df, x)) );    
    udat_close(df);
}

void Test714(void)
{
    UDate d=978103543000.0;
    UChar temp[20];
    UErrorCode status = U_ZERO_ERROR;
    UDateFormat *fmt;
    UChar *result;
    const char* expect =  "7:25:43 AM";
    
    fmt= udat_open(UDAT_MEDIUM,UDAT_NONE ,"en_US_CA", NULL, -1, &status);
    if(U_FAILURE(status))
    {
        log_err("FAIL: error in creating the dateformat using medium time style and NO date style: %s\n", 
            myErrorName(status));
    }
    result =myFormatit(fmt, d);
    u_uastrcpy(temp, expect);
    if (u_strcmp(result, temp)!=0){
      log_err("Fail: %s != %s\n", austrdup(result), expect);
    }
    else{
      log_verbose("Ok: %s == %s\n", austrdup(result), expect );
    }
        
    udat_close(fmt);
}

/*INTERNAL FUNCTION USED */

UChar* myFormatit(UDateFormat* datdef, UDate d1)
{
    UChar *result1=NULL;
    int32_t resultlength, resultlengthneeded;
    UErrorCode status = U_ZERO_ERROR;
    
    resultlength=0;
    resultlengthneeded=udat_format(datdef, d1, NULL, resultlength, NULL, &status);
    if(status==U_BUFFER_OVERFLOW_ERROR)
    {
        status=U_ZERO_ERROR;
        resultlength=resultlengthneeded+1;
        /*result1=(UChar*)malloc(sizeof(UChar) * resultlength);*/ /*this leaks*/
        result1=(UChar*)ctst_malloc(sizeof(UChar) * resultlength); /*this won't*/
        udat_format(datdef, d1, result1, resultlength, NULL, &status);
    }
    if(U_FAILURE(status))
    {
        log_err("FAIL: Error in formatting using udat_format(.....): %s\n", myErrorName(status));
        return 0;
    }
    
    
    return result1;

}

/*eof*/
