/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2009 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 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, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: Alexander Larsson <alexl@redhat.com>
 */

#include <config.h>

#include <stdio.h>
#include <unistd.h>
#include <locale.h>
#include <errno.h>

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

static gchar **locations = NULL;
static char *from_charset = NULL;
static char *to_charset = NULL;
static gboolean decompress = FALSE;
static gboolean compress = FALSE;
static gboolean gzip = FALSE;
static gboolean fallback = FALSE;

static GOptionEntry entries[] = {
  {"decompress", 0, 0, G_OPTION_ARG_NONE, &decompress, "decompress", NULL},
  {"compress", 0, 0, G_OPTION_ARG_NONE, &compress, "compress", NULL},
  {"gzip", 0, 0, G_OPTION_ARG_NONE, &gzip, "use gzip format", NULL},
  {"from-charset", 0, 0, G_OPTION_ARG_STRING, &from_charset, "from charset", NULL},
  {"to-charset", 0, 0, G_OPTION_ARG_STRING, &to_charset, "to charset", NULL},
  {"fallback", 0, 0, G_OPTION_ARG_NONE, &fallback, "use fallback", NULL},
  {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &locations, "locations", NULL},
  {NULL}
};

static void
decompressor_file_info_notify_cb (GZlibDecompressor *decompressor,
                                  GParamSpec *pspec,
                                  gpointer data)
{
  GFileInfo *file_info;
  const gchar *filename;

  file_info = g_zlib_decompressor_get_file_info (decompressor);
  if (file_info == NULL)
    return;

  filename = g_file_info_get_name (file_info);
  if (filename)
    g_printerr ("Decompressor filename: %s\n", filename);
}

static void
cat (GFile * file)
{
  GInputStream *in;
  char buffer[1024 * 8 + 1];
  char *p;
  gssize res;
  gboolean close_res;
  GError *error;
  GConverter *conv;
  GCharsetConverter *cconv = NULL;

  error = NULL;
  in = (GInputStream *) g_file_read (file, NULL, &error);
  if (in == NULL)
    {
      /* Translators: the first %s is the program name, the second one  */
      /* is the URI of the file, the third is the error message.        */
      g_printerr ("%s: %s: error opening file: %s\n",
		  g_get_prgname (), g_file_get_uri (file), error->message);
      g_error_free (error);
      return;
    }

  if (decompress)
    {
      GInputStream *old;
      conv = (GConverter *)g_zlib_decompressor_new (gzip?G_ZLIB_COMPRESSOR_FORMAT_GZIP:G_ZLIB_COMPRESSOR_FORMAT_ZLIB);
      old = in;
      in = (GInputStream *) g_converter_input_stream_new (in, conv);
      g_signal_connect (conv, "notify::file-info", G_CALLBACK (decompressor_file_info_notify_cb), NULL);
      g_object_unref (conv);
      g_object_unref (old);
    }

  if (from_charset && to_charset)
    {
      cconv = g_charset_converter_new (to_charset, from_charset, &error);
      conv = (GConverter *)cconv;
      if (conv)
	{
	  GInputStream *old;

	  g_charset_converter_set_use_fallback (cconv, fallback);

	  old = in;
	  in = (GInputStream *) g_converter_input_stream_new (in, conv);
	  g_object_unref (conv);
	  g_object_unref (old);
	}
      else
	{
	  g_printerr ("%s: Can't convert between charsets: %s\n",
		      g_get_prgname (), error->message);
	}
    }

  if (compress)
    {
      GInputStream *old;
      GFileInfo *in_file_info;

      in_file_info = g_file_query_info (file,
                                        G_FILE_ATTRIBUTE_STANDARD_NAME ","
                                        G_FILE_ATTRIBUTE_TIME_MODIFIED,
                                        G_FILE_QUERY_INFO_NONE,
                                        NULL,
                                        &error);
      if (in_file_info == NULL)
        {
          g_printerr ("%s: %s: error reading file info: %s\n",
                      g_get_prgname (), g_file_get_uri (file), error->message);
          g_error_free (error);
          return;
        }

      conv = (GConverter *)g_zlib_compressor_new(gzip?G_ZLIB_COMPRESSOR_FORMAT_GZIP:G_ZLIB_COMPRESSOR_FORMAT_ZLIB, -1);
      g_zlib_compressor_set_file_info (G_ZLIB_COMPRESSOR (conv), in_file_info);
      old = in;
      in = (GInputStream *) g_converter_input_stream_new (in, conv);
      g_object_unref (conv);
      g_object_unref (old);
      g_object_unref (in_file_info);
    }

  while (1)
    {
      res =
	g_input_stream_read (in, buffer, sizeof (buffer) - 1, NULL, &error);
      if (res > 0)
	{
	  ssize_t written;

	  p = buffer;
	  while (res > 0)
	    {
	      written = write (STDOUT_FILENO, p, res);

	      if (written == -1 && errno != EINTR)
		{
		  /* Translators: the first %s is the program name, the */
		  /* second one is the URI of the file.                 */
		  g_printerr ("%s: %s, error writing to stdout",
			      g_get_prgname (), g_file_get_uri (file));
		  goto out;
		}
	      res -= written;
	      p += written;
	    }
	}
      else if (res < 0)
	{
	  g_printerr ("%s: %s: error reading: %s\n",
		      g_get_prgname (), g_file_get_uri (file),
		      error->message);
	  g_error_free (error);
	  error = NULL;
	  break;
	}
      else if (res == 0)
	break;
    }

 out:

  close_res = g_input_stream_close (in, NULL, &error);
  if (!close_res)
    {
      g_printerr ("%s: %s:error closing: %s\n",
		  g_get_prgname (), g_file_get_uri (file), error->message);
      g_error_free (error);
    }

  if (cconv != NULL && fallback)
    {
      guint num = g_charset_converter_get_num_fallbacks (cconv);
      if (num > 0)
	g_printerr ("Number of fallback errors: %u\n", num);
    }
}

int
main (int argc, char *argv[])
{
  GError *error = NULL;
  GOptionContext *context = NULL;
  GFile *file;
  int i;

  g_type_init ();

  context =
    g_option_context_new ("LOCATION... - concatenate LOCATIONS "
			  "to standard output.");

  g_option_context_set_summary (context, "filter files");

  g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
  g_option_context_parse (context, &argc, &argv, &error);

  g_option_context_free (context);

  if (error != NULL)
    {
      g_printerr ("Error parsing commandline options: %s\n", error->message);
      g_printerr ("\n");
      g_printerr ("Try \"%s --help\" for more information.",
		  g_get_prgname ());
      g_printerr ("\n");
      g_error_free(error);
      return 1;
    }

  if (!locations)
    {
      g_printerr ("%s: missing locations", g_get_prgname ());
      g_printerr ("\n");
      g_printerr ("Try \"%s --help\" for more information.",
		  g_get_prgname ());
      g_printerr ("\n");
      return 1;
    }

  i = 0;

  do
    {
      file = g_file_new_for_commandline_arg (locations[i]);
      cat (file);
      g_object_unref (file);
    }
  while (locations[++i] != NULL);

  return 0;
}
