// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 1997-2010, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/

#include "unicode/ucnv.h"
#include "unicode/ucnv_err.h"

#include "cintltst.h"
#include "ustr_cnv.h"
#include <string.h>
void TestDefaultConverterError(void); /* keep gcc happy */
void TestDefaultConverterSet(void); /* keep gcc happy */


/* This makes sure that a converter isn't leaked when an error is passed to 
    u_getDefaultConverter */
void TestDefaultConverterError(void) {
    UErrorCode          err                 =   U_ZERO_ERROR;

    /* Remove the default converter */
    ucnv_close(u_getDefaultConverter(&err));

    if (U_FAILURE(err)) {
        log_err("Didn't expect a failure yet %s\n", myErrorName(err));
        return;
    }

    /* Set to any radom error state */
    err = U_FILE_ACCESS_ERROR;
    if (u_getDefaultConverter(&err) != NULL) {
        log_err("Didn't expect to get a converter on a failure\n");
    }
}

/* Get the default converter. Copy its name. Put it back. */
static void copyDefaultConverterName(char *out, UErrorCode *status) {
    UConverter *defConv;
    const char *itsName;
    out[0]=0;
    if(U_FAILURE(*status)) return;
    defConv = u_getDefaultConverter(status);
    /* get its name */
    itsName = ucnv_getName(defConv, status);
    if(U_FAILURE(*status)) return;
    strcpy(out, itsName); 
    /* put it back. */
    u_releaseDefaultConverter(defConv); 
}

/* 
  Changing the default name may not affect the actual name from u_getDefaultConverter
   ( for example, if UTF-8 is the fixed converter ).
  But, if it does cause a change, that change should be reflected when the converter is
  set back.
*/
void TestDefaultConverterSet(void) {
    UErrorCode status = U_ZERO_ERROR;
    static char defaultName[UCNV_MAX_CONVERTER_NAME_LENGTH + 1];
    static char nameBeforeSet[UCNV_MAX_CONVERTER_NAME_LENGTH + 1];
    static char nameAfterSet[UCNV_MAX_CONVERTER_NAME_LENGTH + 1];
    static char nameAfterRestore[UCNV_MAX_CONVERTER_NAME_LENGTH + 1];
    static const char SET_TO[]="iso-8859-3";
    strcpy(defaultName, ucnv_getDefaultName());

    log_verbose("getDefaultName returned %s\n", defaultName);

   /* first, flush any extant converter */
   u_flushDefaultConverter();
   copyDefaultConverterName(nameBeforeSet, &status);
   log_verbose("name from u_getDefaultConverter() = %s\n", nameBeforeSet);
   u_flushDefaultConverter();
   ucnv_setDefaultName(SET_TO);
   copyDefaultConverterName(nameAfterSet, &status);
   log_verbose("name from u_getDefaultConverter() after set to %s (%s) = %s\n", SET_TO, ucnv_getDefaultName(), nameAfterSet);
   ucnv_setDefaultName(defaultName);
   copyDefaultConverterName(nameAfterRestore, &status);
   log_verbose("name from u_getDefaultConverter() after restore = %s\n", nameAfterRestore);
   u_flushDefaultConverter();

   if(U_FAILURE(status)) {
      log_err("Error in test: %s\n", u_errorName(status));
   } else {
      if(!strcmp(nameBeforeSet, nameAfterSet)) { /* changing the default didn't affect. */
          log_info("Skipping test: ucnv_setDefaultName() did not affect actual name of %s\n", nameBeforeSet);
      } else {
          if(strcmp(nameBeforeSet, nameAfterRestore)) {
               log_err("Error: u_getDefaultConverter() is still returning %s (expected %s) even though default converter was set back to %s (was %s)\n", nameAfterRestore, nameBeforeSet, defaultName , SET_TO);
          } else {
              log_verbose("Test passed. \n");
          }
      }
   }
}


