/* xgettext Desktop Entry backend.
   Copyright (C) 2014, 2018-2020 Free Software Foundation, Inc.

   This file was written by Daiki Ueno <ueno@gnu.org>, 2014.

   This program 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.

   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 General Public License for more details.

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

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

/* Specification.  */
#include "x-desktop.h"

#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "message.h"
#include "xgettext.h"
#include "xg-message.h"
#include "error.h"
#include "error-progname.h"
#include "xalloc.h"
#include "xvasprintf.h"
#include "mem-hash-map.h"
#include "gettext.h"
#include "read-desktop.h"
#include "po-charset.h"
#include "c-ctype.h"

#define _(s) gettext(s)

#define SIZEOF(a) (sizeof(a) / sizeof(a[0]))

/* ====================== Keyword set customization.  ====================== */

/* The syntax of a Desktop Entry file is defined at
   https://standards.freedesktop.org/desktop-entry-spec/latest/index.html

   Basically, values with 'localestring' type can be localized.
   However, the values of 'Icon', while being localizable, are not supported
   by xgettext.  See the documentation for more info.

   The type of a value is determined by looking at the key associated
   with it.  The list of available keys are listed on:
   https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s04.html  */

static hash_table keywords;
static bool default_keywords = true;

static void
add_keyword (const char *name, hash_table *keywords, bool is_list)
{
  if (name == NULL)
    default_keywords = false;
  else
    {
      if (keywords->table == NULL)
        hash_init (keywords, 100);

      desktop_add_keyword (keywords, name, is_list);
    }
}

void
x_desktop_keyword (const char *name)
{
  add_keyword (name, &keywords, false);
}

static void
init_keywords (void)
{
  if (default_keywords)
    {
      if (keywords.table == NULL)
        hash_init (&keywords, 100);

      desktop_add_default_keywords (&keywords);
      default_keywords = false;
    }
}

typedef struct extract_desktop_reader_ty extract_desktop_reader_ty;
struct extract_desktop_reader_ty
{
  DESKTOP_READER_TY

  message_list_ty *mlp;
};

static void
extract_desktop_handle_group (struct desktop_reader_ty *reader,
                              const char *group)
{
  savable_comment_reset ();
}

static void
extract_desktop_handle_pair (struct desktop_reader_ty *reader,
                             lex_pos_ty *key_pos,
                             const char *key,
                             const char *locale,
                             const char *value)
{
  extract_desktop_reader_ty *extract_reader =
    (extract_desktop_reader_ty *) reader;
  void *keyword_value;

  if (!locale                   /* Skip already translated entry.  */
      && hash_find_entry (&keywords, key, strlen (key), &keyword_value) == 0)
    {
      bool is_list = (bool) keyword_value;

      remember_a_message (extract_reader->mlp, NULL,
                          desktop_unescape_string (value, is_list), false,
                          false, null_context, key_pos,
                          NULL, savable_comment, false);
    }
  savable_comment_reset ();
}

static void
extract_desktop_handle_comment (struct desktop_reader_ty *reader,
                                const char *buffer)
{
  size_t buflen = strlen (buffer);
  size_t bufpos = 0;

  while (bufpos < buflen
         && c_isspace (buffer[bufpos]))
    ++bufpos;
  while (buflen >= bufpos
         && c_isspace (buffer[buflen - 1]))
    --buflen;
  if (bufpos < buflen)
    {
      char *comment = xstrdup (buffer);
      comment[buflen] = 0;
      savable_comment_add (&comment[bufpos]);
      free (comment);
    }
}

static void
extract_desktop_handle_blank (struct desktop_reader_ty *reader,
                              const char *s)
{
  savable_comment_reset ();
}

static desktop_reader_class_ty extract_methods =
  {
    sizeof (extract_desktop_reader_ty),
    NULL,
    NULL,
    extract_desktop_handle_group,
    extract_desktop_handle_pair,
    extract_desktop_handle_comment,
    extract_desktop_handle_blank
  };

void
extract_desktop (FILE *f,
                 const char *real_filename, const char *logical_filename,
                 flag_context_list_table_ty *flag_table,
                 msgdomain_list_ty *mdlp)
{
  desktop_reader_ty *reader = desktop_reader_alloc (&extract_methods);
  extract_desktop_reader_ty *extract_reader =
    (extract_desktop_reader_ty *) reader;

  init_keywords ();
  xgettext_current_source_encoding = po_charset_utf8;

  extract_reader->mlp = mdlp->item[0]->messages;

  desktop_parse (reader, f, real_filename, logical_filename);
  desktop_reader_free (reader);

  reader = NULL;
}
