/*
 * Copyright © 2012 Red Hat, Inc
 *
 * This library 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 library 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 library; if not, see <http://www.gnu.org/licenses/>.
 *
 * Author: Matthias Clasen
 */

#include "config.h"

#include <stdlib.h>
#include <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <locale.h>

#ifdef HAVE_LIBELF
#include <libelf.h>
#include <gelf.h>
#endif

#ifdef HAVE_MMAP
#include <sys/mman.h>
#endif

#include <gio/gio.h>
#include <glib/gstdio.h>
#include <gi18n.h>

#include "glib/glib-private.h"

#if defined(HAVE_LIBELF) && defined(HAVE_MMAP)
#define USE_LIBELF
#endif

/* GResource functions {{{1 */
static GResource *
get_resource (const gchar *file)
{
  gchar *content;
  gsize size;
  GResource *resource;
  GBytes *data;

  resource = NULL;

  if (g_file_get_contents (file, &content, &size, NULL))
    {
      data = g_bytes_new_take (content, size);
      resource = g_resource_new_from_data (data, NULL);
      g_bytes_unref (data);
    }

  return resource;
}

static void
list_resource (GResource   *resource,
               const gchar *path,
               const gchar *section,
               const gchar *prefix,
               gboolean     details)
{
  gchar **children;
  gsize size;
  guint32 flags;
  gint i;
  gchar *child;
  GError *error = NULL;
  gint len;

  children = g_resource_enumerate_children (resource, path, 0, &error);
  if (error)
    {
      g_printerr ("%s\n", error->message);
      g_error_free (error);
      return;
    }
  for (i = 0; children[i]; i++)
    {
      child = g_strconcat (path, children[i], NULL);

      len = MIN (strlen (child), strlen (prefix));
      if (strncmp (child, prefix, len) != 0)
        {
          g_free (child);
          continue;
        }

      if (g_resource_get_info (resource, child, 0, &size, &flags, NULL))
        {
          if (details)
            g_print ("%s%s%6"G_GSIZE_FORMAT " %s %s\n", section, section[0] ? " " : "", size, (flags & G_RESOURCE_FLAGS_COMPRESSED) ? "c" : "u", child);
          else
            g_print ("%s\n", child);
        }
      else
        list_resource (resource, child, section, prefix, details);

      g_free (child);
    }
  g_strfreev (children);
}

static void
extract_resource (GResource   *resource,
                  const gchar *path)
{
  GBytes *bytes;

  bytes = g_resource_lookup_data (resource, path, 0, NULL);
  if (bytes != NULL)
    {
      gconstpointer data;
      gsize size, written;

      data = g_bytes_get_data (bytes, &size);
      written = fwrite (data, 1, size, stdout);
      if (written < size)
        g_printerr ("Data truncated\n");
      g_bytes_unref (bytes);
    }
}

/* Elf functions {{{1 */

#ifdef USE_LIBELF

static Elf *
get_elf (const gchar *file,
         gint        *fd)
{
  Elf *elf;

  if (elf_version (EV_CURRENT) == EV_NONE )
    return NULL;

  *fd = g_open (file, O_RDONLY, 0);
  if (*fd < 0)
    return NULL;

  elf = elf_begin (*fd, ELF_C_READ, NULL);
  if (elf == NULL)
    {
      g_close (*fd, NULL);
      *fd = -1;
      return NULL;
    }

  if (elf_kind (elf) != ELF_K_ELF)
    {
      g_close (*fd, NULL);
      *fd = -1;
      return NULL;
    }

  return elf;
}

typedef gboolean (*SectionCallback) (GElf_Shdr   *shdr,
                                     const gchar *name,
                                     gpointer     data);

static void
elf_foreach_resource_section (Elf             *elf,
                              SectionCallback  callback,
                              gpointer         data)
{
  size_t shstrndx, shnum;
  size_t scnidx;
  Elf_Scn *scn;
  GElf_Shdr *shdr, shdr_mem;
  const gchar *section_name;

  elf_getshdrstrndx (elf, &shstrndx);
  g_assert (shstrndx >= 0);

  elf_getshdrnum (elf, &shnum);
  g_assert (shnum >= 0);

  for (scnidx = 1; scnidx < shnum; scnidx++)
    {
      scn = elf_getscn (elf, scnidx);
      if (scn == NULL)
        continue;

      shdr = gelf_getshdr (scn, &shdr_mem);
      if (shdr == NULL)
        continue;

      if (shdr->sh_type != SHT_PROGBITS)
        continue;

      section_name = elf_strptr (elf, shstrndx, shdr->sh_name);
      if (section_name == NULL ||
          !g_str_has_prefix (section_name, ".gresource."))
        continue;

      if (!callback (shdr, section_name + strlen (".gresource."), data))
        break;
    }
}

static GResource *
resource_from_section (GElf_Shdr *shdr,
                       int        fd)
{
  gsize page_size, page_offset;
  char *contents;
  GResource *resource;

  resource = NULL;

  page_size = sysconf(_SC_PAGE_SIZE);
  page_offset = shdr->sh_offset % page_size;
  contents = mmap (NULL,  shdr->sh_size + page_offset,
                   PROT_READ, MAP_PRIVATE, fd, shdr->sh_offset - page_offset);
  if (contents != MAP_FAILED)
    {
      GBytes *bytes;
      GError *error = NULL;

      bytes = g_bytes_new_static (contents + page_offset, shdr->sh_size);
      resource = g_resource_new_from_data (bytes, &error);
      g_bytes_unref (bytes);
      if (error)
        {
          g_printerr ("%s\n", error->message);
          g_error_free (error);
        }
    }
  else
    {
      g_printerr ("Can't mmap resource section");
    }

  return resource;
}

typedef struct
{
  int fd;
  const gchar *section;
  const gchar *path;
  gboolean details;
  gboolean found;
} CallbackData;

static gboolean
list_resources_cb (GElf_Shdr   *shdr,
                   const gchar *section,
                   gpointer     data)
{
  CallbackData *d = data;
  GResource *resource;

  if (d->section && strcmp (section, d->section) != 0)
    return TRUE;

  d->found = TRUE;

  resource = resource_from_section (shdr, d->fd);
  list_resource (resource, "/",
                 d->section ? "" : section,
                 d->path,
                 d->details);
  g_resource_unref (resource);

  if (d->section)
    return FALSE;

  return TRUE;
}

static void
elf_list_resources (Elf         *elf,
                    int          fd,
                    const gchar *section,
                    const gchar *path,
                    gboolean     details)
{
  CallbackData data;

  data.fd = fd;
  data.section = section;
  data.path = path;
  data.details = details;
  data.found = FALSE;

  elf_foreach_resource_section (elf, list_resources_cb, &data);

  if (!data.found)
    g_printerr ("Can't find resource section %s\n", section);
}

static gboolean
extract_resource_cb (GElf_Shdr   *shdr,
                     const gchar *section,
                     gpointer     data)
{
  CallbackData *d = data;
  GResource *resource;

  if (d->section && strcmp (section, d->section) != 0)
    return TRUE;

  d->found = TRUE;

  resource = resource_from_section (shdr, d->fd);
  extract_resource (resource, d->path);
  g_resource_unref (resource);

  if (d->section)
    return FALSE;

  return TRUE;
}

static void
elf_extract_resource (Elf         *elf,
                      int          fd,
                      const gchar *section,
                      const gchar *path)
{
  CallbackData data;

  data.fd = fd;
  data.section = section;
  data.path = path;
  data.found = FALSE;

  elf_foreach_resource_section (elf, extract_resource_cb, &data);

  if (!data.found)
    g_printerr ("Can't find resource section %s\n", section);
}

static gboolean
print_section_name (GElf_Shdr   *shdr,
                    const gchar *name,
                    gpointer     data)
{
  g_print ("%s\n", name);
  return TRUE;
}

#endif /* USE_LIBELF */

  /* Toplevel commands {{{1 */

static void
cmd_sections (const gchar *file,
              const gchar *section,
              const gchar *path,
              gboolean     details)
{
  GResource *resource;

#ifdef USE_LIBELF

  Elf *elf;
  gint fd;

  if ((elf = get_elf (file, &fd)))
    {
      elf_foreach_resource_section (elf, print_section_name, NULL);
      elf_end (elf);
      close (fd);
    }
  else

#endif

  if ((resource = get_resource (file)))
    {
      /* No sections */
      g_resource_unref (resource);
    }
  else
    {
      g_printerr ("Don't know how to handle %s\n", file);
#ifndef USE_LIBELF
      g_printerr ("gresource is built without elf support\n");
#endif
    }
}

static void
cmd_list (const gchar *file,
          const gchar *section,
          const gchar *path,
          gboolean     details)
{
  GResource *resource;

#ifdef USE_LIBELF
  Elf *elf;
  int fd;

  if ((elf = get_elf (file, &fd)))
    {
      elf_list_resources (elf, fd, section, path ? path : "", details);
      elf_end (elf);
      close (fd);
    }
  else

#endif

  if ((resource = get_resource (file)))
    {
      list_resource (resource, "/", "", path ? path : "", details);
      g_resource_unref (resource);
    }
  else
    {
      g_printerr ("Don't know how to handle %s\n", file);
#ifndef USE_LIBELF
      g_printerr ("gresource is built without elf support\n");
#endif
    }
}

static void
cmd_extract (const gchar *file,
             const gchar *section,
             const gchar *path,
             gboolean     details)
{
  GResource *resource;

#ifdef USE_LIBELF

  Elf *elf;
  int fd;

  if ((elf = get_elf (file, &fd)))
    {
      elf_extract_resource (elf, fd, section, path);
      elf_end (elf);
      close (fd);
    }
  else

#endif

  if ((resource = get_resource (file)))
    {
      extract_resource (resource, path);
      g_resource_unref (resource);
    }
  else
    {
      g_printerr ("Don't know how to handle %s\n", file);
#ifndef USE_LIBELF
      g_printerr ("gresource is built without elf support\n");
#endif
    }
}

static gint
cmd_help (gboolean     requested,
          const gchar *command)
{
  const gchar *description;
  const gchar *synopsis;
  gchar *option;
  GString *string;

  option = NULL;

  string = g_string_new (NULL);

  if (command == NULL)
    ;

  else if (strcmp (command, "help") == 0)
    {
      description = _("Print help");
      synopsis = _("[COMMAND]");
    }

  else if (strcmp (command, "sections") == 0)
    {
      description = _("List sections containing resources in an elf FILE");
      synopsis = _("FILE");
    }

  else if (strcmp (command, "list") == 0)
    {
      description = _("List resources\n"
                      "If SECTION is given, only list resources in this section\n"
                      "If PATH is given, only list matching resources");
      synopsis = _("FILE [PATH]");
      option = g_strdup_printf ("[--section %s]", _("SECTION"));
    }

  else if (strcmp (command, "details") == 0)
    {
      description = _("List resources with details\n"
                      "If SECTION is given, only list resources in this section\n"
                      "If PATH is given, only list matching resources\n"
                      "Details include the section, size and compression");
      synopsis = _("FILE [PATH]");
      option = g_strdup_printf ("[--section %s]", _("SECTION"));
    }

  else if (strcmp (command, "extract") == 0)
    {
      description = _("Extract a resource file to stdout");
      synopsis = _("FILE PATH");
      option = g_strdup_printf ("[--section %s]", _("SECTION"));
    }

  else
    {
      g_string_printf (string, _("Unknown command %s\n\n"), command);
      requested = FALSE;
      command = NULL;
    }

  if (command == NULL)
    {
      g_string_append (string,
      _("Usage:\n"
        "  gresource [--section SECTION] COMMAND [ARGS…]\n"
        "\n"
        "Commands:\n"
        "  help                      Show this information\n"
        "  sections                  List resource sections\n"
        "  list                      List resources\n"
        "  details                   List resources with details\n"
        "  extract                   Extract a resource\n"
        "\n"
        "Use “gresource help COMMAND” to get detailed help.\n\n"));
    }
  else
    {
      g_string_append_printf (string, _("Usage:\n  gresource %s%s%s %s\n\n%s\n\n"),
                              option ? option : "", option ? " " : "", command, synopsis[0] ? synopsis : "", description);

      g_string_append (string, _("Arguments:\n"));

      if (option)
        g_string_append (string,
                         _("  SECTION   An (optional) elf section name\n"));

      if (strstr (synopsis, _("[COMMAND]")))
        g_string_append (string,
                       _("  COMMAND   The (optional) command to explain\n"));

      if (strstr (synopsis, _("FILE")))
        {
          if (strcmp (command, "sections") == 0)
            g_string_append (string,
                             _("  FILE      An elf file (a binary or a shared library)\n"));
          else
            g_string_append (string,
                             _("  FILE      An elf file (a binary or a shared library)\n"
                               "            or a compiled resource file\n"));
        }

      if (strstr (synopsis, _("[PATH]")))
        g_string_append (string,
                       _("  PATH      An (optional) resource path (may be partial)\n"));
      else if (strstr (synopsis, _("PATH")))
        g_string_append (string,
                       _("  PATH      A resource path\n"));

      g_string_append (string, "\n");
    }

  if (requested)
    g_print ("%s", string->str);
  else
    g_printerr ("%s\n", string->str);

  g_free (option);
  g_string_free (string, TRUE);

  return requested ? 0 : 1;
}

/* main {{{1 */

int
main (int argc, char *argv[])
{
  gchar *section = NULL;
  gboolean details = FALSE;
  void (* function) (const gchar *, const gchar *, const gchar *, gboolean);

#ifdef G_OS_WIN32
  gchar *tmp;
#endif

  setlocale (LC_ALL, GLIB_DEFAULT_LOCALE);
  textdomain (GETTEXT_PACKAGE);

#ifdef G_OS_WIN32
  tmp = _glib_get_locale_dir ();
  bindtextdomain (GETTEXT_PACKAGE, tmp);
  g_free (tmp);
#else
  bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
#endif

#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif

  if (argc < 2)
    return cmd_help (FALSE, NULL);

  if (argc > 3 && strcmp (argv[1], "--section") == 0)
    {
      section = argv[2];
      argv = argv + 2;
      argc -= 2;
    }

  if (strcmp (argv[1], "help") == 0)
    return cmd_help (TRUE, argv[2]);

  else if (argc == 4 && strcmp (argv[1], "extract") == 0)
    function = cmd_extract;

  else if (argc == 3 && strcmp (argv[1], "sections") == 0)
    function = cmd_sections;

  else if ((argc == 3 || argc == 4) && strcmp (argv[1], "list") == 0)
    {
      function = cmd_list;
      details = FALSE;
    }
  else if ((argc == 3 || argc == 4) && strcmp (argv[1], "details") == 0)
    {
      function = cmd_list;
      details = TRUE;
    }
  else
    return cmd_help (FALSE, argv[1]);

  (* function) (argv[2], section, argc > 3 ? argv[3] : NULL, details);

  return 0;
}

/* vim:set foldmethod=marker: */
