/**
 *******************************************************************************
 * Copyright (C) 2002-2006, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 *******************************************************************************
 */
#include "unicode/utypes.h"

#if !UCONFIG_NO_SERVICE || !UCONFIG_NO_TRANSLITERATION

#include "unicode/resbund.h"
#include "cmemory.h"
#include "ustrfmt.h"
#include "locutil.h"
#include "charstr.h"
#include "ucln_cmn.h"
#include "uassert.h"
#include "umutex.h"

// see LocaleUtility::getAvailableLocaleNames
static U_NAMESPACE_QUALIFIER Hashtable * LocaleUtility_cache = NULL;

#define UNDERSCORE_CHAR ((UChar)0x005f)
#define AT_SIGN_CHAR    ((UChar)64)
#define PERIOD_CHAR     ((UChar)46)

/*
 ******************************************************************
 */

/**
 * Release all static memory held by Locale Utility.  
 */
U_CDECL_BEGIN
static UBool U_CALLCONV service_cleanup(void) {
    if (LocaleUtility_cache) {
        delete LocaleUtility_cache;
        LocaleUtility_cache = NULL;
    }
    return TRUE;
}
U_CDECL_END

U_NAMESPACE_BEGIN

UnicodeString&
LocaleUtility::canonicalLocaleString(const UnicodeString* id, UnicodeString& result)
{
  if (id == NULL) {
    result.setToBogus();
  } else {
    // Fix case only (no other changes) up to the first '@' or '.' or
    // end of string, whichever comes first.  In 3.0 I changed this to
    // stop at first '@' or '.'.  It used to run out to the end of
    // string.  My fix makes the tests pass but is probably
    // structurally incorrect.  See below.  [alan 3.0]

    // TODO: Doug, you might want to revise this...
    result = *id;
    int32_t i = 0;
    int32_t end = result.indexOf(AT_SIGN_CHAR);
    int32_t n = result.indexOf(PERIOD_CHAR);
    if (n >= 0 && n < end) {
        end = n;
    }
    if (end < 0) {
        end = result.length();
    }
    n = result.indexOf(UNDERSCORE_CHAR);
    if (n < 0) {
      n = end;
    }
    for (; i < n; ++i) {
      UChar c = result.charAt(i);
      if (c >= 0x0041 && c <= 0x005a) {
        c += 0x20;
        result.setCharAt(i, c);
      }
    }
    for (n = end; i < n; ++i) {
      UChar c = result.charAt(i);
      if (c >= 0x0061 && c <= 0x007a) {
        c -= 0x20;
        result.setCharAt(i, c);
      }
    }
  }
  return result;

#if 0
    // This code does a proper full level 2 canonicalization of id.
    // It's nasty to go from UChar to char to char to UChar -- but
    // that's what you have to do to use the uloc_canonicalize
    // function on UnicodeStrings.

    // I ended up doing the alternate fix (see above) not for
    // performance reasons, although performance will certainly be
    // better, but because doing a full level 2 canonicalization
    // causes some tests to fail.  [alan 3.0]

    // TODO: Doug, you might want to revisit this...
    result.setToBogus();
    if (id != 0) {
        int32_t buflen = id->length() + 8; // space for NUL
        char* buf = (char*) uprv_malloc(buflen);
        char* canon = (buf == 0) ? 0 : (char*) uprv_malloc(buflen);
        if (buf != 0 && canon != 0) {
            U_ASSERT(id->extract(0, INT32_MAX, buf, buflen) < buflen);
            UErrorCode ec = U_ZERO_ERROR;
            uloc_canonicalize(buf, canon, buflen, &ec);
            if (U_SUCCESS(ec)) {
                result = UnicodeString(canon);
            }
        }
        uprv_free(buf);
        uprv_free(canon);
    }
    return result;
#endif
}

Locale&
LocaleUtility::initLocaleFromName(const UnicodeString& id, Locale& result)
{
    enum { BUFLEN = 128 }; // larger than ever needed

    if (id.isBogus() || id.length() >= BUFLEN) {
        result.setToBogus();
    } else {
        /*
         * We need to convert from a UnicodeString to char * in order to
         * create a Locale.
         *
         * Problem: Locale ID strings may contain '@' which is a variant
         * character and cannot be handled by invariant-character conversion.
         *
         * Hack: Since ICU code can handle locale IDs with multiple encodings
         * of '@' (at least for EBCDIC; it's not known to be a problem for
         * ASCII-based systems),
         * we use regular invariant-character conversion for everything else
         * and manually convert U+0040 into a compiler-char-constant '@'.
         * While this compilation-time constant may not match the runtime
         * encoding of '@', it should be one of the encodings which ICU
         * recognizes.
         *
         * There should be only at most one '@' in a locale ID.
         */
        char buffer[BUFLEN];
        int32_t prev, i;
        prev = 0;
        for(;;) {
            i = id.indexOf((UChar)0x40, prev);
            if(i < 0) {
                // no @ between prev and the rest of the string
                id.extract(prev, INT32_MAX, buffer + prev, BUFLEN - prev, US_INV);
                break; // done
            } else {
                // normal invariant-character conversion for text between @s
                id.extract(prev, i - prev, buffer + prev, BUFLEN - prev, US_INV);
                // manually "convert" U+0040 at id[i] into '@' at buffer[i]
                buffer[i] = '@';
                prev = i + 1;
            }
        }
        result = Locale::createFromName(buffer);
    }
    return result;
}

UnicodeString&
LocaleUtility::initNameFromLocale(const Locale& locale, UnicodeString& result)
{
    if (locale.isBogus()) {
        result.setToBogus();
    } else {
        result.append(UnicodeString(locale.getName(), -1, US_INV));
    }
    return result;
}

const Hashtable*
LocaleUtility::getAvailableLocaleNames(const UnicodeString& bundleID)
{
    // LocaleUtility_cache is a hash-of-hashes.  The top-level keys
    // are path strings ('bundleID') passed to
    // ures_openAvailableLocales.  The top-level values are
    // second-level hashes.  The second-level keys are result strings
    // from ures_openAvailableLocales.  The second-level values are
    // garbage ((void*)1 or other random pointer).

    UErrorCode status = U_ZERO_ERROR;
    Hashtable* cache;
    umtx_lock(NULL);
    cache = LocaleUtility_cache;
    umtx_unlock(NULL);

    if (cache == NULL) {
        cache = new Hashtable(status);
        if (cache == NULL || U_FAILURE(status)) {
            return NULL; // catastrophic failure; e.g. out of memory
        }
        cache->setValueDeleter(uhash_deleteHashtable);
        Hashtable* h; // set this to final LocaleUtility_cache value
        umtx_lock(NULL);
        h = LocaleUtility_cache;
        if (h == NULL) {
            LocaleUtility_cache = h = cache;
            cache = NULL;
            ucln_common_registerCleanup(UCLN_COMMON_SERVICE, service_cleanup);
        }
        umtx_unlock(NULL);
        if(cache != NULL) {
          delete cache;
        }
        cache = h;
    }

    U_ASSERT(cache != NULL);

    Hashtable* htp;
    umtx_lock(NULL);
    htp = (Hashtable*) cache->get(bundleID);
    umtx_unlock(NULL);

    if (htp == NULL) {
        htp = new Hashtable(status);
        if (htp && U_SUCCESS(status)) {
            CharString cbundleID(bundleID);
            const char* path = (const char*) cbundleID;
            if (*path == 0) path = NULL; // empty string => NULL
            UEnumeration *uenum = ures_openAvailableLocales(path, &status);
            for (;;) {
                const UChar* id = uenum_unext(uenum, NULL, &status);
                if (id == NULL) {
                    break;
                }
                htp->put(UnicodeString(id), (void*)htp, status);
            }
            uenum_close(uenum);
            if (U_FAILURE(status)) {
                delete htp;
                return NULL;
            }
            umtx_lock(NULL);
            cache->put(bundleID, (void*)htp, status);
            umtx_unlock(NULL);
        }
    }
    return htp;
}

UBool
LocaleUtility::isFallbackOf(const UnicodeString& root, const UnicodeString& child)
{
    return child.indexOf(root) == 0 &&
      (child.length() == root.length() ||
       child.charAt(root.length()) == UNDERSCORE_CHAR);
}

U_NAMESPACE_END

/* !UCONFIG_NO_SERVICE */
#endif


