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

  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;
}
