/**
 * @file config.h
 *
 * Config - Configuration data handling for the capi tracer.
 *
 * Copyright: 2002-2003 Thomas Wintergerst. All rights reserved.
 *
 * $FreeBSD$
 * $Id: config.h,v 1.1.2.1 2006/02/28 21:35:42 thomas Exp $
 * Project  CAPI for BSD
 * Target   capitrace - Tracing CAPI calls and messages
 * @date    16.09.2002
 * @author  "Thomas Wintergerst" <twinterg@gmx.de>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef __CONFIG_H
#define __CONFIG_H

#include <stddef.h> // size_t
#include <list>
#include <string>

#ifndef __CMDOPT2_H
#  include "cmdopt2.h"
#endif





// === Public declarations ===============================================





// === Class declarations ================================================





/**
 * Class for configuration data handling.
 *
 * This class is implemented as a singleton, i.e. there will be exactly one
 * object instance of this class. This object will be defined as a global static
 * variable exported by this module. Thus there is no need for a GetInstance()
 * method like in the general singleton pattern.
 */
class CConfig
{
   public:
      /// An enumeration of the possible tasks of the program.
      enum TaskToExecute_t
      {
         TASK_UNKNOWN,          ///< No task specified on the command line.
         TASK_ERROR,            ///< An error occurred evaluation the command
                                ///< line.
         TASK_USAGE,            ///< The usage hints shall be put out.
         TASK_START_TRACER,     ///< One or more tracers shall be started.
         TASK_INTERPRET_TRACE   ///< A trace file shall be interpreted.
      };
      
      /// Collection of configuration data for a CAPI tracer.
      struct TracerConfig_t
      {
         bool         fIsCtlrTracer;
         unsigned int uCtlrNum;
         bool         fIncludeFctCalls;
         bool         fIncludeMessages;
         bool         fIncludeDataB3Msgs;
         bool         fIncludeDataB3Blocks;
         size_t       nDataB3BlockLen;
         std::string  strTraceFile;
         
         /// The constructor is only to ensure members are set to defined values.
         TracerConfig_t ()
            {
               fIsCtlrTracer        = false;
               uCtlrNum             = 0;
               fIncludeFctCalls     = false;
               fIncludeMessages     = false;
               fIncludeDataB3Msgs   = false;
               fIncludeDataB3Blocks = false;
               nDataB3BlockLen      = 0;
            }
            
      }; // TracerConfig_t
      
      /// A list of CAPI tracer configuration data structures.
      typedef std::list<TracerConfig_t> CTracerConfigList;
      
      
      
      /**
       * Constructor.
       */
      CConfig (void);
      
      /**
       * Destructor.
       */
      ~CConfig (void);
      
      /**
       * Perform general initialization.
       *
       * As this class is designed to create a static object, the constructor
       * will not get enough information for initializing the object. This will
       * thus be done by calling this member function.
       *
       * The main task is to set all internal member variables to reasonable
       * defaults. In addition the short program name is determined from the
       * argument specified. It is expected to be a file name, possibly
       * including some path specification. The basename of this file name will
       * be set as the program name.
       *
       * @param pszProgFileName I: The file name of the current program, maybe
       *                           including a path specification.
       *
       * @retval None.
       *
       * @throws std::invalid_argument
       *                        The argument is the NULL pointer or the empty
       *                        string.
       */
      void Init
         (const char *pszProgFileName);

      /**
       * Evalutate the command line.
       *
       * The command line is evaluated in runs up to a non-option argument. This
       * ending argument will specify a tracer file, regardless of the task to
       * execute. Up to this argument any option is allowed, but the three
       * options for the task specification are special.
       *
       * Trace interpretation and trace creation are distinct operations. A
       * single program run may not perform both actions. In addition to this an
       * application tracer may only be started once.
       *
       * When starting multiple tracers, the settings for the last one created
       * will be inherited by the next one. If this is not wanted, it may be
       * changed by specifying the respective options again with different
       * parameters. Every option representing a simple switch accepts an
       * optional parameter that may set the options value explicitly to "true"
       * or "false.
       *
       * @param iArgc           I: The number of command line arguments in
       *                           papszArgv.
       * @param papszArgv       I: The command line arguments as an array of
       *                           pointers to character vectors.
       *
       * @retval TASK_UNKNOWN   No main action specified, i.e. neither "-i",
       *                        "-a" nor "-c#" was specified on the command
       *                        line.
       * @retval TASK_ERROR     An error occurred evaluating the command line.
       * @retval TASK_USAGE     Only the help text shall be printed.
       * @retval TASK_START_TRACER
       *                        The task is to start one or more tracers.
       * @retval TASK_INTERPRET_TRACE
       *                        The task is to interpret a formerly created
       *                        CAPI trace file.
       */
      TaskToExecute_t EvalCommandLine
         (int    iArgc,
          char **papszArgv);

      /**
       * Print hints for using this program.
       */
      void Usage (void);

      /**
       * General configuration: Get program name.
       */
      const char *GetProgName (void);
      
      /**
       * Interpreter configuration: Get the input file name.
       */
      const std::string &GetInterpretSourceFileName (void);
      
      /**
       * Interpreter configuration: Get flag for Data-B3 message output.
       */
      bool GetInterpretDataB3Msgs (void);
      
      /**
       * Interpreter configuration: Get flag for Data-B3 data block output.
       */
      bool GetInterpretDataB3Blocks (void);
      
      /**
       * Interpreter configuration: Get maximum output length of Data-B3 data
       * blocks if output is enabled.
       */
      size_t GetInterpretDataB3BlockLen (void);
      
      /**
       * Interpreter configuration: Get flag for optional hexadecimal output of
       * the CAPI message.
       */
      bool GetInterpretHexOutput (void);
      
      /**
       * Interpreter configuration: Get the optional output file name.
       */
      const std::string &GetInterpretOutputFileName (void);
      
      /**
       * Tracer configuration: Get an iterator to the beginning of the list of
       * tracer specifications.
       */
      const CTracerConfigList::const_iterator GetTracerConfigStartIterator (void);

      /**
       * Tracer configuration: Get an iterator to the end of the list of tracer
       * specifications.
       */
      const CTracerConfigList::const_iterator GetTracerConfigEndIterator (void);



   protected:



   private:
      /// The short program file name.
      std::string m_strProgName;
      
      /// Interpreter configuration: The source file name.
      std::string m_strInterpretSourceFileName;
      
      /// Interpreter configuration: Flag for Data-B3 message output.
      bool m_fDataB3MsgOutput;
      
      /// Interpreter configuration: Flag for Data-B3 data block output.
      bool m_fDataB3BlockOutput;
      
      /// Interpreter configuration: Maximum size of data blocks for output.
      unsigned int m_uDataB3BlockLen;
      
      /// Interpreter configuration: Flag for additional hexadecimal output.
      bool m_fHexOutput;
      
      /// Interpreter configuration: Optional output file name.
      std::string m_strOutputFileName;
      
      /// Tracer configuration: The place to store the next tracer specification
      /// from the command line.
      TracerConfig_t m_nextTracerConfig;
      
      /// Tracer configuration: The list of tracers to start.
      CTracerConfigList m_tracerConfigList;
      
      /// The command line evaluator object.
      thwutil::CCmdLineEvaluator m_oCmdLineEvaluator;
      
      /// The option object for the main action "interpret trace file".
      thwutil::CBooleanCmdOpt m_oCmdOptInterpretTraceFile;
      
      /// The option object to start an application tracer.
      thwutil::CBooleanCmdOpt m_oCmdOptAppTracer;
      
      /// The option object to start a controller tracer.
      thwutil::CUIntParamCmdOpt m_oCmdOptCtlrTracer;
      
      /// The option object for inclusion of function calls in a trace.
      thwutil::CBooleanCmdOpt m_oCmdOptIncludeFctCalls;
      
      /// The option object for inclusion of messages in a trace.
      thwutil::CBooleanCmdOpt m_oCmdOptIncludeMessages;
      
      /// The option object for inclusion of Data-B3 messages in output or
      /// trace.
      thwutil::CBooleanCmdOpt m_oCmdOptIncludeDataB3Msgs;
      
      /// The option object for inclusion of Data-B3 data block content in
      /// output or trace.
      thwutil::CBooleanCmdOpt m_oCmdOptIncludeDataB3Blocks;
      
      /// The option object for the maximum length of Data-B3 data blocks in
      /// output or trace.
      thwutil::CUIntParamCmdOpt m_oCmdOptDataB3BlockLen;
      
      /// The option object for the hexadecimal output switch.
      thwutil::CBooleanCmdOpt m_oCmdOptHexOutput;
      
      /// The option object for the output file name for a trace interpreter.
      thwutil::CStringParamCmdOpt m_oCmdOptOutputFileName;
      
      /// The option object for help output by "-h".
      thwutil::CBooleanCmdOpt m_oCmdOptHelp1;
      
      /// The option object for help output by "-?".
      thwutil::CBooleanCmdOpt m_oCmdOptHelp2;



}; // CConfig





/// The global config object.
extern CConfig e_oConfig;





// === Prototypes of interface functions =================================





#endif // __CONFIG_H
