#include <libintl.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <sys/stat.h>
#include <ctype.h>
#include "locale_impl.h"
#include "libc.h"
#include "atomic.h"

struct binding {
  struct binding* next;
  int dirlen;
  volatile int active;
  char* domainname;
  char* dirname;
  char buf[];
};

static void* volatile bindings;

static char* gettextdir(const char* domainname, size_t* dirlen) {
  struct binding* p;
  for (p = bindings; p; p = p->next) {
    if (!strcmp(p->domainname, domainname) && p->active) {
      *dirlen = p->dirlen;
      return (char*)p->dirname;
    }
  }
  return 0;
}

char* bindtextdomain(const char* domainname, const char* dirname) {
  static volatile int lock[2];
  struct binding *p, *q;

  if (!domainname)
    return 0;
  if (!dirname)
    return gettextdir(domainname, &(size_t){0});

  size_t domlen = strlen(domainname);
  size_t dirlen = strlen(dirname);
  if (domlen > NAME_MAX || dirlen >= PATH_MAX) {
    errno = EINVAL;
    return 0;
  }

  LOCK(lock);

  for (p = bindings; p; p = p->next) {
    if (!strcmp(p->domainname, domainname) && !strcmp(p->dirname, dirname)) {
      break;
    }
  }

  if (!p) {
    p = malloc(sizeof *p + domlen + dirlen + 2);
    if (!p) {
      UNLOCK(lock);
      return 0;
    }
    p->next = bindings;
    p->dirlen = dirlen;
    p->domainname = p->buf;
    p->dirname = p->buf + domlen + 1;
    memcpy(p->domainname, domainname, domlen + 1);
    memcpy(p->dirname, dirname, dirlen + 1);
    a_cas_p(&bindings, bindings, p);
  }

  a_store(&p->active, 1);

  for (q = bindings; q; q = q->next) {
    if (!strcmp(p->domainname, domainname) && q != p)
      a_store(&q->active, 0);
  }

  UNLOCK(lock);

  return (char*)p->dirname;
}

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

static const char catlens[] = {8, 10, 7, 10, 11, 11};

struct msgcat {
  struct msgcat* next;
  const void* map;
  size_t map_size;
  void* volatile plural_rule;
  volatile int nplurals;
  char name[];
};

static char* dummy_gettextdomain() {
  return "messages";
}

weak_alias(dummy_gettextdomain, __gettextdomain);

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

char* dcngettext(const char* domainname,
                 const char* msgid1,
                 const char* msgid2,
                 unsigned long int n,
                 int category) {
  static struct msgcat* volatile cats;
  struct msgcat* p;
  struct __locale_struct* loc = CURRENT_LOCALE;
  const struct __locale_map* lm;
  const char *dirname, *locname, *catname;
  size_t dirlen, loclen, catlen, domlen;

  if ((unsigned)category >= LC_ALL)
    goto notrans;

  if (!domainname)
    domainname = __gettextdomain();

  domlen = strlen(domainname);
  if (domlen > NAME_MAX)
    goto notrans;

  dirname = gettextdir(domainname, &dirlen);
  if (!dirname)
    goto notrans;

  lm = loc->cat[category];
  if (!lm) {
  notrans:
    return (char*)((n == 1) ? msgid1 : msgid2);
  }
  locname = lm->name;

  catname = catnames[category];
  catlen = catlens[category];
  loclen = strlen(locname);

  size_t namelen = dirlen + 1 + loclen + 1 + catlen + 1 + domlen + 3;
  char name[namelen + 1], *s = name;

  memcpy(s, dirname, dirlen);
  s[dirlen] = '/';
  s += dirlen + 1;
  memcpy(s, locname, loclen);
  s[loclen] = '/';
  s += loclen + 1;
  memcpy(s, catname, catlen);
  s[catlen] = '/';
  s += catlen + 1;
  memcpy(s, domainname, domlen);
  s[domlen] = '.';
  s[domlen + 1] = 'm';
  s[domlen + 2] = 'o';
  s[domlen + 3] = 0;

  for (p = cats; p; p = p->next)
    if (!strcmp(p->name, name))
      break;

  if (!p) {
    void* old_cats;
    size_t map_size;
    const void* map = __map_file(name, &map_size);
    if (!map)
      goto notrans;
    p = malloc(sizeof *p + namelen + 1);
    if (!p) {
      __munmap((void*)map, map_size);
      goto notrans;
    }
    p->map = map;
    p->map_size = map_size;
    memcpy(p->name, name, namelen + 1);
    do {
      old_cats = cats;
      p->next = old_cats;
    } while (a_cas_p(&cats, old_cats, p) != old_cats);
  }

  const char* trans = __mo_lookup(p->map, p->map_size, msgid1);
  if (!trans)
    goto notrans;

  /* Non-plural-processing gettext forms pass a null pointer as
   * msgid2 to request that dcngettext suppress plural processing. */
  if (!msgid2)
    return (char*)trans;

  if (!p->plural_rule) {
    const char* rule = "n!=1;";
    unsigned long np = 2;
    const char* r = __mo_lookup(p->map, p->map_size, "");
    char* z;
    while (r && strncmp(r, "Plural-Forms:", 13)) {
      z = strchr(r, '\n');
      r = z ? z + 1 : 0;
    }
    if (r) {
      r += 13;
      while (isspace(*r))
        r++;
      if (!strncmp(r, "nplurals=", 9)) {
        np = strtoul(r + 9, &z, 10);
        r = z;
      }
      while (*r && *r != ';')
        r++;
      if (*r) {
        r++;
        while (isspace(*r))
          r++;
        if (!strncmp(r, "plural=", 7))
          rule = r + 7;
      }
    }
    a_store(&p->nplurals, np);
    a_cas_p(&p->plural_rule, 0, (void*)rule);
  }
  if (p->nplurals) {
    unsigned long plural = __pleval(p->plural_rule, n);
    if (plural > p->nplurals)
      goto notrans;
    while (plural--) {
      size_t rem = p->map_size - (trans - (char*)p->map);
      size_t l = strnlen(trans, rem);
      if (l + 1 >= rem)
        goto notrans;
      trans += l + 1;
    }
  }
  return (char*)trans;
}

char* dcgettext(const char* domainname, const char* msgid, int category) {
  return dcngettext(domainname, msgid, 0, 1, category);
}

char* dngettext(const char* domainname,
                const char* msgid1,
                const char* msgid2,
                unsigned long int n) {
  return dcngettext(domainname, msgid1, msgid2, n, LC_MESSAGES);
}

char* dgettext(const char* domainname, const char* msgid) {
  return dcngettext(domainname, msgid, 0, 1, LC_MESSAGES);
}
