// Internal functions to obtain the current locales.

#include "third_party/glibc_locales/library/current_locale.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>

#include "third_party/glibc_locales/common/langinfo.h"
#include "third_party/glibc_locales/common/localeinfo.h"
#include "third_party/glibc_locales/glibc_locales.h"
#include "third_party/glibc_locales/locale_archive.h"

// We store the current locale values in thread-local static variables.  This
// assumes that users never rely on setlocale() to change the locale that is
// seen by a thread that already exists at the time of the call.  Doing so
// would require explicit synchronization to avoid data races (glibc is not
// quite thread-safe for a locale-aware function being called at the same time
// as setlocale()), and supporting it here would add substantial complexity.
__thread static struct google_locale_struct global_locale;
#define global_ctype_data (global_locale.category_data[GOOGLE_LC_CTYPE])
#define global_collate_data (global_locale.category_data[GOOGLE_LC_COLLATE])

// Pointer to the locale currently in use.  This will be the global_locale
// object unless google_uselocale() has been called to set a thread-local
// locale, in which case this will point to that (user-owned) locale.
__thread static google_locale_t current_locale = NULL;

// If we have a locale passed in through uselocale(). we stash it here.
void google_set_current_locales(google_locale_t locale) {
  // If we've been given a locale, use it.
  if (locale != NULL) {
    current_locale = locale;
    return;
  }

  // Return if we've been called from setlocale() and this is a no-op
  // because we have a thread-local locale overriding the setlocale state.
  if (uselocale(NULL) != LC_GLOBAL_LOCALE) {
    return;
  }

  // If we got here, we need to set our locales to match glibc's global locale.
  // Get the current names from glibc.
  char *ctype_name = setlocale(LC_CTYPE, NULL);
  char *collate_name = setlocale(LC_COLLATE, NULL);

  // Adjust the current pointer to use the global locale.
  current_locale = &global_locale;

  // Replace the locale components in global_locale, if needed.
  const char *archive_data = 0;
  struct locrecent *locale_data = 0;

  if (global_ctype_data == NULL ||
      strcmp(global_ctype_data->name, ctype_name)) {
    archive_data = locale_archive_create()->data;
    locale_data = google_find_locale_data(archive_data, ctype_name);

    if (locale_data == NULL) return;

    const void *addr =
        archive_data + locale_data->record[GOOGLE_LC_CTYPE].offset;
    size_t len = locale_data->record[GOOGLE_LC_CTYPE].len;

    if (global_ctype_data) free(global_ctype_data);
    global_ctype_data =
        google_load_locale_data(ctype_name, GOOGLE_LC_CTYPE, addr, len);

    /* Update the special members.  */
    if (global_locale.category_data[GOOGLE_LC_CTYPE] != NULL) {
      union locale_data_value *ctypes =
          global_locale.category_data[GOOGLE_LC_CTYPE]->values;
      global_locale.ctype_b =
          (const unsigned short int *)
              ctypes[GOOGLE_NL_ITEM_INDEX(GOOGLE_NL_CTYPE_CLASS)]
                  .string +
          128;
      global_locale.ctype_tolower =
          (const int *)ctypes[GOOGLE_NL_ITEM_INDEX(GOOGLE_NL_CTYPE_TOLOWER)]
              .string +
          128;
      global_locale.ctype_toupper =
          (const int *)ctypes[GOOGLE_NL_ITEM_INDEX(GOOGLE_NL_CTYPE_TOUPPER)]
              .string +
          128;
    } else {
      global_locale.ctype_b = NULL;
      global_locale.ctype_tolower = NULL;
      global_locale.ctype_toupper = NULL;
    }
  }

  if (global_collate_data == NULL ||
      strcmp(global_collate_data->name, collate_name)) {
    // If we've already found the relevant data for the CTYPE component,
    // re-use that rather than searching for it again.
    if (!archive_data) archive_data = locale_archive_create()->data;
    if (!locale_data || strcmp(ctype_name, collate_name))
      locale_data = google_find_locale_data(archive_data, collate_name);

    if (locale_data == NULL) return;

    const void *addr =
        archive_data + locale_data->record[GOOGLE_LC_COLLATE].offset;
    size_t len = locale_data->record[GOOGLE_LC_COLLATE].len;

    if (global_collate_data) free(global_collate_data);
    global_collate_data =
        google_load_locale_data(collate_name, GOOGLE_LC_COLLATE, addr, len);
  }
}

google_locale_t google_get_current_locale() {
  if (global_ctype_data == NULL || global_collate_data == NULL)
    google_set_current_locales(NULL);

  return current_locale;
}
