/* gettext.c - gettext module */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2009 Free Software Foundation, Inc.
 *
 *  GRUB is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/normal.h>
#include <grub/file.h>
#include <grub/kernel.h>
#include <grub/i18n.h>

GRUB_MOD_LICENSE ("GPLv3+");

/*
   .mo file information from:
   http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html .
*/

static const char *(*grub_gettext_original) (const char *s);

struct grub_gettext_msg
{
  char *name;
  char *translated;
};

struct header
{
  grub_uint32_t magic;
  grub_uint32_t version;
  grub_uint32_t number_of_strings;
  grub_uint32_t offset_original;
  grub_uint32_t offset_translation;
};

struct string_descriptor 
{
  grub_uint32_t length;
  grub_uint32_t offset;
};

struct grub_gettext_context
{
  grub_file_t fd_mo;
  grub_off_t grub_gettext_offset_original;
  grub_off_t grub_gettext_offset_translation;
  grub_size_t grub_gettext_max;
  int grub_gettext_max_log;
  struct grub_gettext_msg *grub_gettext_msg_list;
};

static struct grub_gettext_context main_context, secondary_context;

#define MO_MAGIC_NUMBER 		0x950412de

static grub_err_t
grub_gettext_pread (grub_file_t file, void *buf, grub_size_t len,
		    grub_off_t offset)
{
  if (len == 0)
    return GRUB_ERR_NONE;
  if (grub_file_seek (file, offset) == (grub_off_t) - 1)
    return grub_errno;
  if (grub_file_read (file, buf, len) != (grub_ssize_t) len)
    {
      if (!grub_errno)
	grub_error (GRUB_ERR_READ_ERROR, N_("premature end of file"));
      return grub_errno;
    }
  return GRUB_ERR_NONE;
}

static char *
grub_gettext_getstr_from_position (struct grub_gettext_context *ctx,
				   grub_off_t off,
				   grub_size_t position)
{
  grub_off_t internal_position;
  grub_size_t length;
  grub_off_t offset;
  char *translation;
  struct string_descriptor desc;
  grub_err_t err;

  internal_position = (off + position * sizeof (desc));

  err = grub_gettext_pread (ctx->fd_mo, (char *) &desc,
			    sizeof (desc), internal_position);
  if (err)
    return NULL;
  length = grub_cpu_to_le32 (desc.length);
  offset = grub_cpu_to_le32 (desc.offset);

  translation = grub_malloc (length + 1);
  if (!translation)
    return NULL;

  err = grub_gettext_pread (ctx->fd_mo, translation, length, offset);
  if (err)
    {
      grub_free (translation);
      return NULL;
    }
  translation[length] = '\0';

  return translation;
}

static const char *
grub_gettext_gettranslation_from_position (struct grub_gettext_context *ctx,
					   grub_size_t position)
{
  if (!ctx->grub_gettext_msg_list[position].translated)
    ctx->grub_gettext_msg_list[position].translated
      = grub_gettext_getstr_from_position (ctx,
					   ctx->grub_gettext_offset_translation,
					   position);
  return ctx->grub_gettext_msg_list[position].translated;
}

static const char *
grub_gettext_getstring_from_position (struct grub_gettext_context *ctx,
				      grub_size_t position)
{
  if (!ctx->grub_gettext_msg_list[position].name)
    ctx->grub_gettext_msg_list[position].name
      = grub_gettext_getstr_from_position (ctx,
					   ctx->grub_gettext_offset_original,
					   position);
  return ctx->grub_gettext_msg_list[position].name;
}

static const char *
grub_gettext_translate_real (struct grub_gettext_context *ctx,
			     const char *orig)
{
  grub_size_t current = 0;
  int i;
  const char *current_string;
  static int depth = 0;

  if (!ctx->grub_gettext_msg_list || !ctx->fd_mo)
    return NULL;

  /* Shouldn't happen. Just a precaution if our own code
     calls gettext somehow.  */
  if (depth > 2)
    return NULL;
  depth++;

  /* Make sure we can use grub_gettext_translate for error messages.  Push
     active error message to error stack and reset error message.  */
  grub_error_push ();

  for (i = ctx->grub_gettext_max_log; i >= 0; i--)
    {
      grub_size_t test;
      int cmp;

      test = current | (1 << i);
      if (test >= ctx->grub_gettext_max)
	continue;

      current_string = grub_gettext_getstring_from_position (ctx, test);

      if (!current_string)
	{
	  grub_errno = GRUB_ERR_NONE;
	  grub_error_pop ();
	  depth--;
	  return NULL;
	}

      /* Search by bisection.  */
      cmp = grub_strcmp (current_string, orig);
      if (cmp <= 0)
	current = test;
      if (cmp == 0)
	{
	  const char *ret = 0;
	  ret = grub_gettext_gettranslation_from_position (ctx, current);
	  if (!ret)
	    {
	      grub_errno = GRUB_ERR_NONE;
	      grub_error_pop ();
	      depth--;
	      return NULL;
	    }
	  grub_error_pop ();
	  depth--;
	  return ret;      
	}
    }

  if (current == 0 && ctx->grub_gettext_max != 0)
    {
      current_string = grub_gettext_getstring_from_position (ctx, 0);

      if (!current_string)
	{
	  grub_errno = GRUB_ERR_NONE;
	  grub_error_pop ();
	  depth--;
	  return NULL;
	}

      if (grub_strcmp (current_string, orig) == 0)
	{
	  const char *ret = 0;
	  ret = grub_gettext_gettranslation_from_position (ctx, current);
	  if (!ret)
	    {
	      grub_errno = GRUB_ERR_NONE;
	      grub_error_pop ();
	      depth--;
	      return NULL;
	    }
	  grub_error_pop ();
	  depth--;
	  return ret;      
	}
    }

  grub_error_pop ();
  depth--;
  return NULL;
}

static const char *
grub_gettext_translate (const char *orig)
{
  const char *ret;
  if (orig[0] == 0)
    return orig;

  ret = grub_gettext_translate_real (&main_context, orig);
  if (ret)
    return ret;
  ret = grub_gettext_translate_real (&secondary_context, orig);
  if (ret)
    return ret;
  return orig;
}

static void
grub_gettext_delete_list (struct grub_gettext_context *ctx)
{
  struct grub_gettext_msg *l = ctx->grub_gettext_msg_list;
  grub_size_t i;

  if (!l)
    return;
  ctx->grub_gettext_msg_list = 0;
  for (i = 0; i < ctx->grub_gettext_max; i++)
    grub_free (l[i].name);
  /* Don't delete the translated message because could be in use.  */
  grub_free (l);
  if (ctx->fd_mo)
    grub_file_close (ctx->fd_mo);
  ctx->fd_mo = 0;
  grub_memset (ctx, 0, sizeof (*ctx));
}

/* This is similar to grub_file_open. */
static grub_err_t
grub_mofile_open (struct grub_gettext_context *ctx,
		  const char *filename)
{
  struct header head;
  grub_err_t err;
  grub_file_t fd;

  /* Using fd_mo and not another variable because
     it's needed for grub_gettext_get_info.  */

  fd = grub_file_open (filename, GRUB_FILE_TYPE_GETTEXT_CATALOG);

  if (!fd)
    return grub_errno;

  err = grub_gettext_pread (fd, &head, sizeof (head), 0);
  if (err)
    {
      grub_file_close (fd);
      return err;
    }

  if (head.magic != grub_cpu_to_le32_compile_time (MO_MAGIC_NUMBER))
    {
      grub_file_close (fd);
      return grub_error (GRUB_ERR_BAD_FILE_TYPE,
			 "mo: invalid mo magic in file: %s", filename);
    }

  if (head.version != 0)
    {
      grub_file_close (fd);
      return grub_error (GRUB_ERR_BAD_FILE_TYPE,
			 "mo: invalid mo version in file: %s", filename);
    }

  ctx->grub_gettext_offset_original = grub_le_to_cpu32 (head.offset_original);
  ctx->grub_gettext_offset_translation = grub_le_to_cpu32 (head.offset_translation);
  ctx->grub_gettext_max = grub_le_to_cpu32 (head.number_of_strings);
  for (ctx->grub_gettext_max_log = 0; ctx->grub_gettext_max >> ctx->grub_gettext_max_log;
       ctx->grub_gettext_max_log++);

  ctx->grub_gettext_msg_list = grub_zalloc (ctx->grub_gettext_max
					    * sizeof (ctx->grub_gettext_msg_list[0]));
  if (!ctx->grub_gettext_msg_list)
    {
      grub_file_close (fd);
      return grub_errno;
    }
  ctx->fd_mo = fd;
  if (grub_gettext != grub_gettext_translate)
    {
      grub_gettext_original = grub_gettext;
      grub_gettext = grub_gettext_translate;
    }
  return 0;
}

/* Returning grub_file_t would be more natural, but grub_mofile_open assigns
   to fd_mo anyway ...  */
static grub_err_t
grub_mofile_open_lang (struct grub_gettext_context *ctx,
		       const char *part1, const char *part2, const char *locale)
{
  char *mo_file;
  grub_err_t err;

  /* mo_file e.g.: /boot/grub/locale/ca.mo   */

  mo_file = grub_xasprintf ("%s%s/%s.mo", part1, part2, locale);
  if (!mo_file)
    return grub_errno;

  err = grub_mofile_open (ctx, mo_file);
  grub_free (mo_file);

  /* Will try adding .gz as well.  */
  if (err)
    {
      grub_errno = GRUB_ERR_NONE;
      mo_file = grub_xasprintf ("%s%s/%s.mo.gz", part1, part2, locale);
      if (!mo_file)
	return grub_errno;
      err = grub_mofile_open (ctx, mo_file);
      grub_free (mo_file);
    }

  /* Will try adding .gmo as well.  */
  if (err)
    {
      grub_errno = GRUB_ERR_NONE;
      mo_file = grub_xasprintf ("%s%s/%s.gmo", part1, part2, locale);
      if (!mo_file)
	return grub_errno;
      err = grub_mofile_open (ctx, mo_file);
      grub_free (mo_file);
    }

  return err;
}

static grub_err_t
grub_gettext_init_ext (struct grub_gettext_context *ctx,
		       const char *locale,
		       const char *locale_dir, const char *prefix)
{
  const char *part1, *part2;
  grub_err_t err;

  grub_gettext_delete_list (ctx);

  if (!locale || locale[0] == 0)
    return 0;

  part1 = locale_dir;
  part2 = "";
  if (!part1 || part1[0] == 0)
    {
      part1 = prefix;
      part2 = "/locale";
    }

  if (!part1 || part1[0] == 0)
    return 0;

  err = grub_mofile_open_lang (ctx, part1, part2, locale);

  /* ll_CC didn't work, so try ll.  */
  if (err)
    {
      char *lang = grub_strdup (locale);
      char *underscore = lang ? grub_strchr (lang, '_') : 0;

      if (underscore)
	{
	  *underscore = '\0';
	  grub_errno = GRUB_ERR_NONE;
	  err = grub_mofile_open_lang (ctx, part1, part2, lang);
	}

      grub_free (lang);
    }

  if (locale[0] == 'e' && locale[1] == 'n'
      && (locale[2] == '\0' || locale[2] == '_'))
    grub_errno = err = GRUB_ERR_NONE;
  return err;
}

static char *
grub_gettext_env_write_lang (struct grub_env_var *var
			     __attribute__ ((unused)), const char *val)
{
  grub_err_t err;
  err = grub_gettext_init_ext (&main_context, val, grub_env_get ("locale_dir"),
			       grub_env_get ("prefix"));
  if (err)
    grub_print_error ();

  err = grub_gettext_init_ext (&secondary_context, val,
			       grub_env_get ("secondary_locale_dir"), 0);
  if (err)
    grub_print_error ();

  return grub_strdup (val);
}

void
grub_gettext_reread_prefix (const char *val)
{
  grub_err_t err;
  err = grub_gettext_init_ext (&main_context, grub_env_get ("lang"), 
			       grub_env_get ("locale_dir"),
			       val);
  if (err)
    grub_print_error ();
}

static char *
read_main (struct grub_env_var *var
	   __attribute__ ((unused)), const char *val)
{
  grub_err_t err;
  err = grub_gettext_init_ext (&main_context, grub_env_get ("lang"), val,
			       grub_env_get ("prefix"));
  if (err)
    grub_print_error ();
  return grub_strdup (val);
}

static char *
read_secondary (struct grub_env_var *var
		__attribute__ ((unused)), const char *val)
{
  grub_err_t err;
  err = grub_gettext_init_ext (&secondary_context, grub_env_get ("lang"), val,
			       0);
  if (err)
    grub_print_error ();

  return grub_strdup (val);
}

static grub_err_t
grub_cmd_translate (grub_command_t cmd __attribute__ ((unused)),
		    int argc, char **args)
{
  if (argc != 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));

  const char *translation;
  translation = grub_gettext_translate (args[0]);
  grub_printf ("%s\n", translation);
  return 0;
}

GRUB_MOD_INIT (gettext)
{
  const char *lang;
  grub_err_t err;

  lang = grub_env_get ("lang");

  err = grub_gettext_init_ext (&main_context, lang, grub_env_get ("locale_dir"),
			       grub_env_get ("prefix"));
  if (err)
    grub_print_error ();
  err = grub_gettext_init_ext (&secondary_context, lang,
			       grub_env_get ("secondary_locale_dir"), 0);
  if (err)
    grub_print_error ();

  grub_register_variable_hook ("locale_dir", NULL, read_main);
  grub_register_variable_hook ("secondary_locale_dir", NULL, read_secondary);

  grub_register_command_p1 ("gettext", grub_cmd_translate,
			    N_("STRING"),
			    /* TRANSLATORS: It refers to passing the string through gettext.
			       So it's "translate" in the same meaning as in what you're 
			       doing now.
			     */
			    N_("Translates the string with the current settings."));

  /* Reload .mo file information if lang changes.  */
  grub_register_variable_hook ("lang", NULL, grub_gettext_env_write_lang);

  /* Preserve hooks after context changes.  */
  grub_env_export ("lang");
  grub_env_export ("locale_dir");
  grub_env_export ("secondary_locale_dir");
}

GRUB_MOD_FINI (gettext)
{
  grub_gettext_delete_list (&main_context);
  grub_gettext_delete_list (&secondary_context);

  grub_gettext = grub_gettext_original;
}
