//===========================================================================
//  $Name: arts++-1-1-a12 $
//  $Id: ArtsFileUtil.hh,v 1.2 2004/04/21 23:51:26 kkeys Exp $
//===========================================================================
//  Copyright Notice
//
//  By accessing this software, arts++, you are duly informed
//  of and agree to be bound by the conditions described below in this
//  notice:
//
//  This software product, arts++, is developed by Daniel W. McRobb, and
//  copyrighted(C) 1998 by the University of California, San Diego
//  (UCSD), with all rights reserved.  UCSD administers the CAIDA grant,
//  NCR-9711092, under which part of this code was developed.
//
//  There is no charge for arts++ software.  You can redistribute it
//  and/or modify it under the terms of the GNU Lesser General Public
//  License, Version 2.1, February 1999, which is incorporated by
//  reference herein.
//
//  arts++ is distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS, OF
//  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE or that the use
//  of it will not infringe on any third party's intellectual
//  property rights.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with arts++.  Copies can also be obtained from:
//
//    http://www.gnu.org/copyleft/lesser.html
//
//  or by writing to:
//
//  Free Software Foundation, Inc.
//  59 Temple Place, Suite 330
//  Boston, MA 02111-1307
//  USA
//
//  Or contact:
//
//    info@caida.org
//===========================================================================

#ifndef _ARTSFILEUTIL_HH_
#define _ARTSFILEUTIL_HH_

#include <string>
#include <vector>

#include "artslocal.h"
#ifdef HAVE_FSTREAM
  #include <fstream>
#else
  #include <fstream.h>
#endif

#include "ArtsProtocolTableAggregatorMap.hh"
#include "ArtsInterfaceMatrixAggregatorMap.hh"
#include "ArtsNextHopTableAggregatorMap.hh"
#include "ArtsAsMatrixAggregatorMap.hh"
#include "ArtsNetMatrixAggregatorMap.hh"
#include "ArtsPortMatrixAggregatorMap.hh"
#include "ArtsTosTableAggregatorMap.hh"
#include "Arts.hh"
#include "ArtsSelectionSet.hh"
#include "ArtsIfIndexSelectionSet.hh"
#include "ArtsObjectTypeSelectionSet.hh"
#include "ArtsTimeIntervalSelectionSet.hh"

//----------------------------------------------------------------------------
//                            class ArtsFileUtil 
//----------------------------------------------------------------------------
//!  This is a utility class that can be used for aggregation of arts++
//!  data.
//----------------------------------------------------------------------------
class ArtsFileUtil
{
public:
  //--------------------------------------------------------------------------
  //                             ArtsFileUtil() 
  //..........................................................................
  //!  constructor
  //--------------------------------------------------------------------------
  ArtsFileUtil();

  //--------------------------------------------------------------------------
  //             ArtsFileUtil(const ArtsFileUtil & artsFileUtil) 
  //..........................................................................
  //!  copy constructor
  //--------------------------------------------------------------------------
  ArtsFileUtil(const ArtsFileUtil & artsFileUtil);

  //--------------------------------------------------------------------------
  //                             ~ArtsFileUtil() 
  //..........................................................................
  //!  destructor
  //--------------------------------------------------------------------------
  ~ArtsFileUtil();
  
  //--------------------------------------------------------------------------
  //     bool Aggregate(const std::string & outFileName,
  //                    const std::vector<std::string> & inFileNames,
  //                    float hours, bool overwrite, bool quiet) const
  //..........................................................................
  //!  Aggregates data in inFileNames and places the results in a file
  //!  named by outFileName.  Hours is the minimum number of hours that
  //!  should be in each aggregate object produced.  A value of 0.0 for
  //!  hours will create an aggregate that covers the entire time period
  //!  seen in the input files.  If overwrite is true, we overwrite the
  //!  output file, else we append to it.  If quiet is false we print a
  //!  '.' character for each object we read as input and a '+' character
  //!  for each object we write as output.  If _portChooser has port choices
  //!  in it, we will generate selected port tables instead of port
  //!  matrices when we have port matrices in the input.
  //--------------------------------------------------------------------------
  bool Aggregate(const std::string & outFileName,
                 const std::vector<std::string> & inFileNames,
                 float hours, bool overwrite, bool quiet) const;

  //--------------------------------------------------------------------------
  //         bool AggregateProtocolTables(const std::string & outFilename, 
  //                                      const std::vector<std::string> & inFilenames, 
  //                                float hours, bool overwrite, 
  //                                bool quiet) const 
  //..........................................................................
  //!  Aggregates protocol table objects in inFileNames and places the
  //!  results in a file named by outFileName.  Hours is the minimum
  //!  number of hours that should be in each aggregate object produced.
  //!  A value of 0.0 for hours will create an aggregate that covers the
  //!  entire time period seen in the input files.  If overwrite is true,
  //!  we overwrite the output file, else we append to it.  If quiet is
  //!  false we print a '.' character for each object we read as input
  //!  and a '+' character for each object we write as output.  Returns
  //!  false if unable to open output file, else returns true.
  //--------------------------------------------------------------------------
  bool AggregateProtocolTables(const std::string & outFilename,
                               const std::vector<std::string> & inFilenames,
                               float hours, bool overwrite,
                               bool quiet) const;
  
  //--------------------------------------------------------------------------
  //        bool AggregateTosTables(const std::string & outFilename, 
  //                                const std::vector<std::string> & inFilenames, 
  //                                float hours, bool overwrite, 
  //                                bool quiet) const 
  //..........................................................................
  //!  Aggregates TOS table objects in inFileNames and places the results
  //!  in a file named by outFileName.  Hours is the minimum number of
  //!  hours that should be in each aggregate object produced.  A value
  //!  of 0.0 for hours will create an aggregate that covers the entire
  //!  time period seen in the input files.  If overwrite is true, we
  //!  overwrite the output file, else we append to it.  If quiet is
  //!  false we print a '.' character for each object we read as input
  //!  and a '+' character for each object we write as output.  Returns
  //!  false if unable to open output file, else returns true.
  //--------------------------------------------------------------------------
  bool AggregateTosTables(const std::string & outFilename,
                          const std::vector<std::string> & inFilenames,
                          float hours, bool overwrite,
                          bool quiet) const;

  //--------------------------------------------------------------------------
  //   bool AggregateInterfaceMatrices(const std::string & outFilename, 
  //                                   const std::vector<std::string> & inFilenames, 
  //                                   float hours, bool overwrite, 
  //                                   bool quiet) const 
  //..........................................................................
  //!  Aggregates interface matrix objects in inFileNames and places the
  //!  results in a file named by outFileName.  Hours is the minimum
  //!  number of hours that should be in each aggregate object produced.
  //!  A value of 0.0 for hours will create an aggregate that covers the
  //!  entire time period seen in the input files.  If overwrite is true,
  //!  we overwrite the output file, else we append to it.  If quiet is
  //!  false we print a '.' character for each object we read as input
  //!  and a '+' character for each object we write as output.  Returns
  //!  false if unable to open output file, else returns true.
  //--------------------------------------------------------------------------
  bool AggregateInterfaceMatrices(const std::string & outFilename,
                                  const std::vector<std::string> & inFilenames,
                                  float hours, bool overwrite,
                                  bool quiet) const;

  //--------------------------------------------------------------------------
  //     bool AggregateNextHopTables(const std::string & outFilename, 
  //                                 const std::vector<std::string> & inFilenames, 
  //                                 float hours, bool overwrite, 
  //                                 bool quiet) const 
  //..........................................................................
  //!  Aggregates IP nexthop table objects in inFileNames and places the
  //!  results in a file named by outFileName.  Hours is the minimum
  //!  number of hours that should be in each aggregate object produced.
  //!  A value of 0.0 for hours will create an aggregate that covers the
  //!  entire time period seen in the input files.  If overwrite is true,
  //!  we overwrite the output file, else we append to it.  If quiet is
  //!  false we print a '.' character for each object we read as input
  //!  and a '+' character for each object we write as output.  Returns
  //!  false if unable to open output file, else returns true.
  //--------------------------------------------------------------------------
  bool AggregateNextHopTables(const std::string & outFilename,
                              const std::vector<std::string> & inFilenames,
                              float hours, bool overwrite,
                              bool quiet) const;

  //--------------------------------------------------------------------------
  //           bool AggregateAsMatrices(const std::string & outFilename, 
  //                                    const std::vector<std::string> & inFilenames, 
  //                            float hours, bool overwrite, 
  //                            bool quiet) const 
  //..........................................................................
  //!  Aggregates AS matrix objects in inFileNames and places the results
  //!  in a file named by outFileName.  Hours is the minimum number of
  //!  hours that should be in each aggregate object produced.  A value
  //!  of 0.0 for hours will create an aggregate that covers the entire
  //!  time period seen in the input files.  If overwrite is true, we
  //!  overwrite the output file, else we append to it.  If quiet is
  //!  false we print a '.' character for each object we read as input
  //!  and a '+' character for each object we write as output.  Returns
  //!  false if unable to open output file, else returns true.
  //--------------------------------------------------------------------------
  bool AggregateAsMatrices(const std::string & outFilename,
                           const std::vector<std::string> & inFilenames,
                           float hours, bool overwrite,
                           bool quiet) const;

  //--------------------------------------------------------------------------
  //       bool AggregateNetMatrices(const std::string & outFilename, 
  //                                 const std::vector<std::string> & inFilenames, 
  //                                 float hours, bool overwrite, 
  //                                 bool quiet) const 
  //..........................................................................
  //!  Aggregates net matrix objects in inFileNames and places the
  //!  results in a file named by outFileName.  Hours is the minimum
  //!  number of hours that should be in each aggregate object produced.
  //!  A value of 0.0 for hours will create an aggregate that covers the
  //!  entire time period seen in the input files.  If overwrite is true,
  //!  we overwrite the output file, else we append to it.  If quiet is
  //!  false we print a '.' character for each object we read as input
  //!  and a '+' character for each object we write as output.  Returns
  //!  false if unable to open output file, else returns true.
  //--------------------------------------------------------------------------
  bool AggregateNetMatrices(const std::string & outFilename,
                            const std::vector<std::string> & inFilenames,
                            float hours, bool overwrite,
                            bool quiet) const;

  //--------------------------------------------------------------------------
  //    bool AggregatePortMatrices(const std::string & outFilename, 
  //                               const std::vector<std::string> & inFilenames, 
  //                               float hours, bool overwrite,
  //                               bool quiet) const 
  //..........................................................................
  //!  Aggregates port matrix objects in inFileNames and places the
  //!  results in a file named by outFileName.  Hours is the minimum
  //!  number of hours that should be in each aggregate object produced.
  //!  A value of 0.0 for hours will create an aggregate that covers the
  //!  entire time period seen in the input files.  If overwrite is true,
  //!  we overwrite the output file, else we append to it.  If quiet is
  //!  false we print a '.' character for each object we read as input
  //!  and a '+' character for each object we write as output.  Returns
  //!  false if unable to open output file, else returns true.
  //--------------------------------------------------------------------------
  bool AggregatePortMatrices(const std::string & outFilename,
                             const std::vector<std::string> & inFilenames,
                             float hours, bool overwrite,
                             bool quiet) const;

  //--------------------------------------------------------------------------
  //       void PortChooser(const char *portRangeExpression) 
  //..........................................................................
  //!  Sets the selection of ports using a string expression.  This can be
  //!  used to aggregate port matrices to selected port tables.
  //--------------------------------------------------------------------------
  void PortChooser(const char *portRangeExpression);
  
  //--------------------------------------------------------------------------
  //       void IfIndexSelectionSet(ArtsIfIndexSelectionSet & ifIndexSet) 
  //..........................................................................
  //!  Sets the selection of particular input interface data for
  //!  aggregation.  Only data from thw selected interfaces will be
  //!  aggregated.
  //--------------------------------------------------------------------------
  void IfIndexSelectionSet(ArtsIfIndexSelectionSet & ifIndexSet);
  
  //--------------------------------------------------------------------------
  //       void IfIndexSelectionSet(const char *ifIndexSelectionExpression) 
  //..........................................................................
  //!  Sets the selection of particular input interface data for
  //!  aggregation using a string expression (a comma seperated list of
  //!  ifIndex values which may also include hyphens to indicate a range).
  //!  Only data from the selected interfaces will be aggregated.
  //--------------------------------------------------------------------------
  void IfIndexSelectionSet(const char *ifIndexSelectionExpression);
  
  //--------------------------------------------------------------------------
  //    void IfIndexCombineSet(ArtsIfIndexSelectionSet & ifIndexCombineSet) 
  //..........................................................................
  //!  Sets the interface combination set.  This causes data for all
  //!  interfaces in \c ifIndexCombineSet to be aggregated as if they are
  //!  a single interface.  The resulting data will have an ifIndex of 0.
  //--------------------------------------------------------------------------
  void IfIndexCombineSet(ArtsIfIndexSelectionSet & ifIndexCombineSet);
  
  //--------------------------------------------------------------------------
  //       void IfIndexCombineSet(const char *ifIndexSelectionExpression) 
  //..........................................................................
  //!  Sets the interface combination set using a string expression (a
  //!  comma seperated list of ifIndex values which may also include
  //!  hyphens to indicate a range).  This causes data for all
  //!  interfaces in \c ifIndexCombineSet to be aggregated as if they are
  //!  a single interface.  The resulting data will have an ifIndex of 0.
  //--------------------------------------------------------------------------
  void IfIndexCombineSet(const char *ifIndexSelectionExpression);
  
  //--------------------------------------------------------------------------
  //  void ObjectTypeSelectionSet(ArtsObjectTypeSelectionSet & objectTypeSet) 
  //..........................................................................
  //!  Sets the object type selection set.  This causes only particular
  //!  types of objects (AS matrix, port matrix, et. al.) to be selected
  //!  when performaing aggregation.
  //--------------------------------------------------------------------------
  void ObjectTypeSelectionSet(ArtsObjectTypeSelectionSet & objectTypeSet);
  
  //--------------------------------------------------------------------------
  //       void ObjectTypeSelectionSet(const char *objTypeSelectionExpression) 
  //..........................................................................
  //!  Sets the object type selection set using a string expression (a
  //!  comma separated list of object type names).  This causes only
  //!  particular types of objects (AS matrix, port matrix, et. al.) to be
  //!  selected when performaing aggregation.
  //  
  //--------------------------------------------------------------------------
  void ObjectTypeSelectionSet(const char *objTypeSelectionExpression);
  
  //--------------------------------------------------------------------------
  // void 
  // TimeIntervalSelectionSet(ArtsTimeIntervalSelectionSet & timeIntervalSet) 
  //..........................................................................
  //!  Sets the time interval selection set.  This causes only objects
  //!  falling within a particular time interval to be selected when
  //!  performing aggregation.
  //--------------------------------------------------------------------------
  void
  TimeIntervalSelectionSet(ArtsTimeIntervalSelectionSet & timeIntervalSet);

  //--------------------------------------------------------------------------
  //      void TimeIntervalSelectionSet(const char *startTimeExpression, 
  //                                    const char *endTimeExpression) 
  //..........................................................................
  //!  Sets the time interval selection set using string expressions.
  //!  This causes only objects falling within a particular time interval
  //!  to be selected when performing aggregation.
  //--------------------------------------------------------------------------
  void TimeIntervalSelectionSet(const char *startTimeExpression,
                                const char *endTimeExpression);

  void NumberOfTopEntries(int numTopEntries);
  
  #ifndef NDEBUG
    //------------------------------------------------------------------------
    //                     static uint32_t NumObjects()
    //........................................................................
    //
    //------------------------------------------------------------------------
    static uint32_t NumObjects()
    {
      return(_numObjects);
    }
  #endif  // NDEBUG
  
private:

  int                           _numTopEntries;
  ArtsPortChooser               _portChooser;
  ArtsIfIndexSelectionSet       _ifIndexSelectionSet;
  ArtsIfIndexSelectionSet       _ifIndexCombineSet;
  ArtsObjectTypeSelectionSet    _objectTypeSelectionSet;
  ArtsTimeIntervalSelectionSet  _timeIntervalSelectionSet;
  
  void FinishProtocolTableAgg(ArtsProtocolTableAggregatorMap & protoAggMap,
                              std::ofstream & out, bool quiet) const;
  void FinishTosTableAgg(ArtsTosTableAggregatorMap & tosAggMap,
                         std::ofstream & out, bool quiet) const;
  void FinishInterfaceMatrixAgg(ArtsInterfaceMatrixAggregatorMap & intfmAggMap,
                                std::ofstream & out, bool quiet) const;
  void FinishNextHopTableAgg(ArtsNextHopTableAggregatorMap & nextHopAggMap,
                             std::ofstream & out, bool quiet) const;
  void FinishAsMatrixAgg(ArtsAsMatrixAggregatorMap & asmAggMap,
                         std::ofstream & out, bool quiet) const;
  void FinishNetMatrixAgg(ArtsNetMatrixAggregatorMap & netmAggMap,
                          std::ofstream & out, bool quiet) const;
  void FinishPortMatrixAgg(ArtsPortMatrixAggregatorMap & portmAggMap,
                           std::ofstream & out, bool quiet) const;
  void AggregateProtocolTableData(ArtsProtocolTableAggregatorMap & protoAggMap,
                                  const Arts & arts, std::ofstream & out,
                                  float hours, bool quiet) const;
  void AggregateTosTableData(ArtsTosTableAggregatorMap & tosAggMap,
                             const Arts & arts, std::ofstream & out,
                             float hours, bool quiet) const;
  void AggregateInterfaceMatrixData(ArtsInterfaceMatrixAggregatorMap & intfmAggMap,
                                    const Arts & arts, std::ofstream & out,
                                    float hours, bool quiet) const;
  void AggregateNextHopTable(ArtsNextHopTableAggregatorMap & nextHopAggMap,
                             const Arts & arts, std::ofstream & out, float hours,
                             bool quiet) const;
  void AggregateAsMatrixData(ArtsAsMatrixAggregatorMap & asmAggMap,
                             const Arts & arts, std::ofstream & out, float hours,
                             bool quiet) const;
  void AggregateNetMatrixData(ArtsNetMatrixAggregatorMap & netmAggMap,
                              const Arts & arts, std::ofstream & out, float hours,
                              bool quiet) const;
  void AggregatePortMatrixData(ArtsPortMatrixAggregatorMap & portmAggMap,
                               const Arts & arts, std::ofstream & out,
                               float hours, bool quiet) const;

  static uint32_t  _numObjects;

};

#endif  // _ARTSFILEUTIL_HH_
