/*
 * 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>

#ifdef G_OS_WIN32
#include "glib/glib-private.h"
#endif

#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, "");
  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: */
