/* Determine the user's language preferences.
   Copyright (C) 2004-2007, 2018-2019 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation; either version 2.1 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */

/* Written by Bruno Haible <bruno@clisp.org>.
   Win32 code originally by Michele Cicciotti <hackbunny@reactos.com>.  */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <stdlib.h>

#if HAVE_CFLOCALECOPYPREFERREDLANGUAGES || HAVE_CFPREFERENCESCOPYAPPVALUE
# include <string.h>
# if HAVE_CFLOCALECOPYPREFERREDLANGUAGES
#  include <CoreFoundation/CFLocale.h>
# elif HAVE_CFPREFERENCESCOPYAPPVALUE
#  include <CoreFoundation/CFPreferences.h>
# endif
# include <CoreFoundation/CFPropertyList.h>
# include <CoreFoundation/CFArray.h>
# include <CoreFoundation/CFString.h>
extern void _nl_locale_name_canonicalize (char *name);
#endif

#if defined _WIN32
# define WIN32_NATIVE
#endif

#ifdef WIN32_NATIVE
# define WIN32_LEAN_AND_MEAN
# include <windows.h>

# ifndef MUI_LANGUAGE_NAME
# define MUI_LANGUAGE_NAME 8
# endif
# ifndef STATUS_BUFFER_OVERFLOW
# define STATUS_BUFFER_OVERFLOW 0x80000005
# endif

extern void _nl_locale_name_canonicalize (char *name);
extern const char *_nl_locale_name_from_win32_LANGID (LANGID langid);
extern const char *_nl_locale_name_from_win32_LCID (LCID lcid);

/* Get the preferences list through the MUI APIs. This works on Windows Vista
   and newer.  */
static const char *
_nl_language_preferences_win32_mui (HMODULE kernel32)
{
  /* DWORD GetUserPreferredUILanguages (ULONG dwFlags,
                                        PULONG pulNumLanguages,
                                        PWSTR pwszLanguagesBuffer,
                                        PULONG pcchLanguagesBuffer);  */
  typedef DWORD (WINAPI *GetUserPreferredUILanguages_func) (ULONG, PULONG, PWSTR, PULONG);
  GetUserPreferredUILanguages_func p_GetUserPreferredUILanguages;

  p_GetUserPreferredUILanguages =
   (GetUserPreferredUILanguages_func)
   GetProcAddress (kernel32, "GetUserPreferredUILanguages");
  if (p_GetUserPreferredUILanguages != NULL)
    {
      ULONG num_languages;
      ULONG bufsize;
      DWORD ret;

      bufsize = 0;
      ret = p_GetUserPreferredUILanguages (MUI_LANGUAGE_NAME,
                                           &num_languages,
                                           NULL, &bufsize);
      if (ret == 0
          && GetLastError () == STATUS_BUFFER_OVERFLOW
          && bufsize > 0)
        {
          WCHAR *buffer = (WCHAR *) malloc (bufsize * sizeof (WCHAR));
          if (buffer != NULL)
            {
              ret = p_GetUserPreferredUILanguages (MUI_LANGUAGE_NAME,
                                                   &num_languages,
                                                   buffer, &bufsize);
              if (ret)
                {
                  /* Convert the list from NUL-delimited WCHAR[] Win32 locale
                     names to colon-delimited char[] Unix locale names.
                     We assume that all these locale names are in ASCII,
                     nonempty and contain no colons.  */
                  char *languages =
                    (char *) malloc (bufsize + num_languages * 10 + 1);
                  if (languages != NULL)
                    {
                      const WCHAR *p = buffer;
                      char *q = languages;
                      ULONG i;
                      for (i = 0; i < num_languages; i++)
                        {
                          char *q1;
                          char *q2;

                          q1 = q;
                          if (i > 0)
                            *q++ = ':';
                          q2 = q;
                          for (; *p != (WCHAR)'\0'; p++)
                            {
                              if ((unsigned char) *p != *p || *p == ':')
                                {
                                  /* A non-ASCII character or a colon inside
                                     the Win32 locale name! Punt.  */
                                  q = q1;
                                  break;
                                }
                              *q++ = (unsigned char) *p;
                            }
                          if (q == q1)
                            /* An unexpected Win32 locale name occurred.  */
                            break;
                          *q = '\0';
                          _nl_locale_name_canonicalize (q2);
                          q = q2 + strlen (q2);
                          p++;
                        }
                      *q = '\0';
                      if (q > languages)
                        {
                          free (buffer);
                          return languages;
                        }
                      free (languages);
                    }
                }
              free (buffer);
            }
        }
    }
  return NULL;
}

/* Get a preference.  This works on Windows ME and newer.  */
static const char *
_nl_language_preferences_win32_ME (HMODULE kernel32)
{
  /* LANGID GetUserDefaultUILanguage (void);  */
  typedef LANGID (WINAPI *GetUserDefaultUILanguage_func) (void);
  GetUserDefaultUILanguage_func p_GetUserDefaultUILanguage;

  p_GetUserDefaultUILanguage =
   (GetUserDefaultUILanguage_func)
   GetProcAddress (kernel32, "GetUserDefaultUILanguage");
  if (p_GetUserDefaultUILanguage != NULL)
    return _nl_locale_name_from_win32_LANGID (p_GetUserDefaultUILanguage ());
  return NULL;
}

/* Get a preference.  This works on Windows 95 and newer.  */
static const char *
_nl_language_preferences_win32_95 ()
{
  HKEY desktop_resource_locale_key;

  if (RegOpenKeyExA (HKEY_CURRENT_USER,
                     "Control Panel\\Desktop\\ResourceLocale",
                     0, KEY_QUERY_VALUE, &desktop_resource_locale_key)
      == NO_ERROR)
    {
      DWORD type;
      BYTE data[8 + 1];
      DWORD data_size = sizeof (data);
      DWORD ret;

      ret = RegQueryValueExA (desktop_resource_locale_key, NULL, NULL,
                              &type, data, &data_size);
      RegCloseKey (desktop_resource_locale_key);

      if (ret == NO_ERROR)
        {
          /* We expect a string, at most 8 bytes long, that parses as a
             hexadecimal number.  */
          if (type == REG_SZ
              && data_size <= sizeof (data)
              && (data_size < sizeof (data)
                  || data[sizeof (data) - 1] == '\0'))
            {
              LCID lcid;
              char *endp;
              /* Ensure it's NUL terminated.  */
              if (data_size < sizeof (data))
                data[data_size] = '\0';
              /* Parse it as a hexadecimal number.  */
              lcid = strtoul ((char *) data, &endp, 16);
              if (endp > (char *) data && *endp == '\0')
                return _nl_locale_name_from_win32_LCID (lcid);
            }
        }
    }
  return NULL;
}

/* Get the system's preference.  This can be used as a fallback.  */
static BOOL CALLBACK
ret_first_language (HMODULE h, LPCSTR type, LPCSTR name, WORD lang, LONG_PTR param)
{
  *(const char **)param = _nl_locale_name_from_win32_LANGID (lang);
  return FALSE;
}
static const char *
_nl_language_preferences_win32_system (HMODULE kernel32)
{
  const char *languages = NULL;
  /* Ignore the warning on mingw here. mingw has a wrong definition of the last
     parameter type of ENUMRESLANGPROC.  */
  EnumResourceLanguages (kernel32, RT_VERSION, MAKEINTRESOURCE (1),
                         ret_first_language, (LONG_PTR)&languages);
  return languages;
}

#endif

/* Determine the user's language preferences, as a colon separated list of
   locale names in XPG syntax
     language[_territory][.codeset][@modifier]
   The result must not be freed; it is statically allocated.
   The LANGUAGE environment variable does not need to be considered; it is
   already taken into account by the caller.  */

const char *
_nl_language_preferences_default (void)
{
#if HAVE_CFLOCALECOPYPREFERREDLANGUAGES || HAVE_CFPREFERENCESCOPYAPPVALUE
  /* MacOS X 10.4 or newer */
  {
    /* Cache the preferences list, since CoreFoundation calls are expensive.  */
    static const char *cached_languages;
    static int cache_initialized;

    if (!cache_initialized)
      {
# if HAVE_CFLOCALECOPYPREFERREDLANGUAGES /* MacOS X 10.5 or newer */
        CFArrayRef prefArray = CFLocaleCopyPreferredLanguages ();
# elif HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.4 or newer */
        CFTypeRef preferences =
          CFPreferencesCopyAppValue (CFSTR ("AppleLanguages"),
                                     kCFPreferencesCurrentApplication);
        if (preferences != NULL
            && CFGetTypeID (preferences) == CFArrayGetTypeID ())
          {
            CFArrayRef prefArray = (CFArrayRef)preferences;
# endif

            int n = CFArrayGetCount (prefArray);
            char buf[256];
            char buf2[256];
            size_t size = 0;
            int i;

            for (i = 0; i < n; i++)
              {
                CFTypeRef element = CFArrayGetValueAtIndex (prefArray, i);
                if (element != NULL
                    && CFGetTypeID (element) == CFStringGetTypeID ()
                    && CFStringGetCString ((CFStringRef)element,
                                           buf, sizeof (buf),
                                           kCFStringEncodingASCII))
                  {
                    strcpy (buf2, buf);
                    _nl_locale_name_canonicalize (buf);
                    size += strlen (buf) + 1;
                    /* Mac OS X 10.12 or newer returns an array of elements of
                       the form "ll-CC" or "ll-Scrp-CC" where ll is a language
                       code, CC is a country code, and Scrp (optional) is a
                       script code.
                       _nl_locale_name_canonicalize converts this to "ll_CC" or
                       "ll_Scrp_CC".
                       Sometimes ll and CC are unrelated, i.e. there is no
                       translation for "ll_CC" but one for "ll".
                       Similarly, in the case with a script, sometimes there is
                       no translation for "ll_Scrp_CC" but one for "ll_Scrp"
                       (after proper canonicalization).
                       Therefore, in the result, we return "ll_CC" followed
                       by "ll", or similarly for the case with a script.  */
                    {
                      char *last_minus = strrchr (buf2, '-');
                      if (last_minus != NULL)
                        {
                          *last_minus = '\0';
                          _nl_locale_name_canonicalize (buf2);
                          size += strlen (buf2) + 1;
                        }
                    }
                    /* Most GNU programs use msgids in English and don't ship
                       an en.mo message catalog.  Therefore when we see "en" or
                       "en-CC" in the preferences list, arrange for gettext()
                       to return the msgid, and ignore all further elements of
                       the preferences list.  */
                    if (buf[0] == 'e' && buf[1] == 'n'
                        && (buf[2] == '\0' || buf[2] == '_'))
                      break;
                  }
                else
                  break;
              }
            if (size > 0)
              {
                char *languages = (char *) malloc (size);

                if (languages != NULL)
                  {
                    char *p = languages;

                    for (i = 0; i < n; i++)
                      {
                        CFTypeRef element =
                          CFArrayGetValueAtIndex (prefArray, i);
                        if (element != NULL
                            && CFGetTypeID (element) == CFStringGetTypeID ()
                            && CFStringGetCString ((CFStringRef)element,
                                                   buf, sizeof (buf),
                                                   kCFStringEncodingASCII))
                          {
                            strcpy (buf2, buf);
                            _nl_locale_name_canonicalize (buf);
                            strcpy (p, buf);
                            p += strlen (buf);
                            *p++ = ':';
                            {
                              char *last_minus = strrchr (buf2, '-');
                              if (last_minus != NULL)
                                {
                                  *last_minus = '\0';
                                  _nl_locale_name_canonicalize (buf2);
                                  strcpy (p, buf2);
                                  p += strlen (buf2);
                                  *p++ = ':';
                                }
                            }
                            if (buf[0] == 'e' && buf[1] == 'n'
                                 && (buf[2] == '\0' || buf[2] == '_'))
                              break;
                          }
                        else
                          break;
                      }
                    *--p = '\0';

                    cached_languages = languages;
                  }
              }

# if HAVE_CFLOCALECOPYPREFERREDLANGUAGES /* MacOS X 10.5 or newer */
        CFRelease (prefArray);
# elif HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.4 or newer */
          }
# endif
        cache_initialized = 1;
      }
    if (cached_languages != NULL)
      return cached_languages;
  }
#endif

#ifdef WIN32_NATIVE
  {
    /* Cache the preferences list, since computing it is expensive.  */
    static const char *cached_languages;
    static int cache_initialized;

    /* Activate the new code only when the GETTEXT_MUI environment variable is
       set, for the time being, since the new code is not well tested.  */
    if (!cache_initialized && getenv ("GETTEXT_MUI") != NULL)
      {
        const char *languages = NULL;
        HMODULE kernel32 = GetModuleHandle ("kernel32");

        if (kernel32 != NULL)
          languages = _nl_language_preferences_win32_mui (kernel32);

        if (languages == NULL && kernel32 != NULL)
          languages = _nl_language_preferences_win32_ME (kernel32);

        if (languages == NULL)
          languages = _nl_language_preferences_win32_95 ();

        if (languages == NULL && kernel32 != NULL)
          languages = _nl_language_preferences_win32_system (kernel32);

        cached_languages = languages;
        cache_initialized = 1;
      }
    if (cached_languages != NULL)
      return cached_languages;
  }
#endif

  return NULL;
}
