/*
 * tools/lvmsar.c
 *
 * Copyright (C) 1998  Heinz Mauelshagen, Sistina Software
 *
 * September 1998
 * October 1999
 * February 2000
 * March 2001
 *
 * LVM is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 * 
 * LVM 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with LVM; see the file COPYING.  If not, write to
 * the Free Software Foundation, 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA. 
 *
 */

/*
 * Changelog
 *
 *    06/10/1999 - implemented support for long options
 *    15/02/2000 - use lvm_error()
 *    23/01/2001 - added call to lvm_init (JT)
 *    13/03/2001 - added support to read lvmsadc(8) created data from <stdin>
 *
 */

#include <lvm_user.h>

char *cmd = NULL;
#ifdef DEBUG
   int opt_d = 0;
#endif

int main ( int argc, char **argv) {
   int c = 0;
   int flag = 0;
   int le = 0;
   int opt_f = 0;
   int opt_s = 0;
   int opt_v = 0;
   int read_sum = 0;
   int reads = 0;
   int writes = 0;
   int write_sum = 0;
   char buffer[80];
#ifdef DEBUG
   char *options = "dfh?sv";
#else
   char *options = "fh?sv";
#endif
   struct option long_options[] = {
#ifdef DEBUG
      { "debug",   no_argument, NULL, 'd'},
#endif
      { "full",    no_argument, NULL, 'f'},
      { "help",    no_argument, NULL, 'h'},
      { "stdin",   no_argument, NULL, 's'},
      { "verbose", no_argument, NULL, 'v'},
      { NULL, 0, NULL, 0}
   };
   char *logfile = NULL;
   char *ptr = NULL;
   FILE *log = NULL;

   /* lvm_init(argc, argv); */
   cmd = basename ( argv[0]);

   SUSER_CHECK;

   while ( ( c = getopt_long ( argc, argv, options,
                               long_options,  NULL)) != EOF) {
      switch ( c) {
#ifdef DEBUG
         case 'd':
            if ( opt_d > 0) {
               fprintf ( stderr, "%s -- d option already given\n\n", cmd);
               return LVM_EINVALID_CMD_LINE;
            }
            opt_d++;
            break;
#endif

         case 'f':
            if ( opt_f > 0) {
               fprintf ( stderr, "%s -- f option already given\n\n", cmd);
               return LVM_EINVALID_CMD_LINE;
            }
            opt_f++;
            break;

         case '?':
            printf ( "\n%s (IOP %d)\n\n%s -- Logical Volume Manager System "
                     "Activity Data Reporter\n\n"
                     "Synopsis:\n"
                     "---------\n\n"
                     "%s\n"
#ifdef DEBUG
                     "\t[-d/--debug]\n"
#endif
                     "\t[-f/--full]\n"
                     "\t[-h/-?/--help]\n"
                     "\t[-s/--stdin]\n"
                     "\t[-v/--verbose]\n"
                     "\tLogFilePath\n",
                     lvm_version, LVM_LIB_IOP_VERSION,  cmd, cmd);
            return 0;
            break;

         case 's':
            if ( opt_s > 0) {
               fprintf ( stderr, "%s -- s option already given\n\n", cmd);
               return LVM_EINVALID_CMD_LINE;
            }
            opt_s++;
            break;

         case 'v':
            if ( opt_v > 0) {
               fprintf ( stderr, "%s -- v option already given\n\n", cmd);
               return LVM_EINVALID_CMD_LINE;
            }
            opt_v++;
            break;

         default:
            fprintf ( stderr, "%s -- invalid command line option \"%c\"\n\n",
                      cmd, c);
            return LVM_EINVALID_CMD_LINE;
      }
   }

   CMD_MINUS_CHK;

   if ( opt_s == 0 && argc - optind != 1) {
      fprintf ( stderr, "%s -- please enter a LogFilePath or use option -s to read from <stdin>\n\n", cmd);
      return LVM_EINVALID_CMD_LINE;
   }

   if ( opt_s == 0) {
      logfile = argv[optind];
      if ( opt_v > 0) printf ( "%s -- opening logfile \"%s\"\n", cmd, logfile);
      if ( ( log = fopen ( logfile, "r")) == NULL) {
         fprintf ( stderr, "%s -- ERROR \"%s\" opening \"%s\" for read\n\n",
                           cmd, lvm_error ( errno), logfile);
         return LVM_ELVMSAR_FOPEN;
      }
   } else {
      logfile = "<stdin>";
      log = stdin;
   }

   if ( opt_v > 0) printf ( "%s -- reading logfile \"%s\"\n", cmd, logfile);
   while ( fgets ( buffer, sizeof ( buffer), log)) {
      ptr = strrchr ( buffer, '\n');
      if ( ptr != NULL) *ptr = 0;

      if ( strchr ( buffer, ' ') == NULL) {
         time_t t;
         /* Timestamp */
         if ( flag > 0) {
            printf ( "Total reads: %8d   Total writes: %8d\n\n",
                     read_sum, write_sum);
            flag = 0; 
         }
         t = atol ( buffer);
         printf ( "\n\n%s-------------------------------------------------\n",
                  ctime ( &t));
      } else if ( strncmp ( buffer, "/dev", 4) == 0) {
         /* Device special */
         if ( flag > 0) {
            printf ( "Total reads: %8d   Total writes: %8d\n\n",
                     read_sum, write_sum);
            flag = 0; 
         }
         ptr = strchr ( buffer, ' ');
         if ( ptr != NULL) *ptr = 0;
         printf ( "Logical volume \"%s\":\n", buffer);
         flag = read_sum = write_sum = 0;
      } else {
         sscanf ( buffer, "%d %d %d", &le, &reads, &writes);
         if ( opt_f > 0) printf ( "LE: %5d  Reads: %8d  Writes: %8d\n",
                                  le, reads, writes);
         read_sum += reads;
         write_sum += writes;
         flag = 1;
      }
   }
   if ( flag > 0) printf ( "Total reads: %8d   Total writes: %8d\n\n",
                           read_sum, write_sum);

   if ( log != stdin) {
      if ( opt_v > 0) printf ( "%s -- closing logfile \"%s\"\n", cmd, logfile);
      if ( fclose ( log) < 0) {
         fprintf ( stderr, "%s -- ERROR \"%s\" closing \"%s\"\n\n",
                           cmd, lvm_error ( errno), logfile);
         return LVM_ELVMSAR_FCLOSE;
      }
   }

   return 0;
}
