/*
 * 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)
{
  int ret;
  size_t shstrndx, shnum;
  size_t scnidx;
  Elf_Scn *scn;
  GElf_Shdr *shdr, shdr_mem;
  const gchar *section_name;

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

  ret = elf_getshdrnum (elf, &shnum);
  g_assert (ret == 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: */
