/* 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, see <http://www.gnu.org/licenses/>.
 *
 * Author: Alexander Larsson <alexl@redhat.com>
 */

#include <config.h>

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

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

#ifdef G_OS_UNIX
#include <unistd.h>
#endif

#ifdef G_OS_WIN32
#include <io.h>
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#endif

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)
	{
	  gssize 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;
}
