#include <locale.h>
#include <string.h>
#include "locale_impl.h"
#include "libc.h"
#include "atomic.h"

const char* __lctrans_impl(const char* msg, const struct __locale_map* lm) {
  const char* trans = 0;
  if (lm)
    trans = __mo_lookup(lm->map, lm->map_size, msg);
  return trans ? trans : msg;
}

const unsigned char* __map_file(const char*, size_t*);
int __munmap(void*, size_t);
char* __strchrnul(const char*, int);

static const char envvars[][12] = {
    "LC_CTYPE",   "LC_NUMERIC",  "LC_TIME",
    "LC_COLLATE", "LC_MONETARY", "LC_MESSAGES",
};

const struct __locale_map* __get_locale(int cat, const char* val) {
  static int lock[2];
  static void* volatile loc_head;
  const struct __locale_map* p;
  struct __locale_map* new = 0;
  const char *path = 0, *z;
  char buf[256];
  size_t l, n;

  if (!*val) {
    ((val = getenv("LC_ALL")) && *val) ||
        ((val = getenv(envvars[cat])) && *val) ||
        ((val = getenv("LANG")) && *val) || (val = "C.UTF-8");
  }

  /* Limit name length and forbid leading dot or any slashes. */
  for (n = 0; n < LOCALE_NAME_MAX && val[n] && val[n] != '/'; n++)
    ;
  if (val[0] == '.' || val[n])
    val = "C.UTF-8";
  int builtin = (val[0] == 'C' && !val[1]) || !strcmp(val, "C.UTF-8") ||
                !strcmp(val, "POSIX");

  if (builtin) {
    if (cat == LC_CTYPE && val[1] == '.')
      return (void*)&__c_dot_utf8;
    return 0;
  }

  for (p = loc_head; p; p = p->next)
    if (!strcmp(val, p->name))
      return p;

  LOCK(lock);

  for (p = loc_head; p; p = p->next)
    if (!strcmp(val, p->name)) {
      UNLOCK(lock);
      return p;
    }

  if (!libc.secure)
    path = getenv("MUSL_LOCPATH");
  /* FIXME: add a default path? */

  if (path)
    for (; *path; path = z + !!*z) {
      z = __strchrnul(path, ':');
      l = z - path - !!*z;
      if (l >= sizeof buf - n - 2)
        continue;
      memcpy(buf, path, l);
      buf[l] = '/';
      memcpy(buf + l + 1, val, n);
      buf[l + 1 + n] = 0;
      size_t map_size;
      const void* map = __map_file(buf, &map_size);
      if (map) {
        new = malloc(sizeof *new);
        if (!new) {
          __munmap((void*)map, map_size);
          break;
        }
        new->map = map;
        new->map_size = map_size;
        memcpy(new->name, val, n);
        new->name[n] = 0;
        new->next = loc_head;
        loc_head = new;
        break;
      }
    }

  /* If no locale definition was found, make a locale map
   * object anyway to store the name, which is kept for the
   * sake of being able to do message translations at the
   * application level. */
  if (!new && (new = malloc(sizeof *new))) {
    new->map = __c_dot_utf8.map;
    new->map_size = __c_dot_utf8.map_size;
    memcpy(new->name, val, n);
    new->name[n] = 0;
    new->next = loc_head;
    loc_head = new;
  }

  /* For LC_CTYPE, never return a null pointer unless the
   * requested name was "C" or "POSIX". */
  if (!new&& cat == LC_CTYPE)
    new = (void*)&__c_dot_utf8;

  UNLOCK(lock);
  return new;
}
