/**
 * @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:40 thomas Exp $
 * Project  CAPI for BSD
 * Target   capitest - Test tool for the functionality of CAPI for BSD
 * @date    19.08.2003
 * @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
#ifndef __CAPISM_H
#  include "capism.h"
#endif





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





// --- some helper macros ---

#define ARRAY_COUNT( a )        (sizeof (a) / sizeof (a [0]))





// === 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_LIST_CTLR,        ///< Print the list of available controllers.
         TASK_IN_CALLS,         ///< Handle incoming calls.
         TASK_OUT_CALLS,        ///< Perform a fixed no. outgoing calls.
         TASK_REP_OUT_CALLS,    ///< Perform repeated outgoing calls.
         TASK_BATCH_CALLS,      ///< Perform a batch of calls.
         TASK_REP_BATCH_CALLS,  ///< Perform a batch of repeated calls.
         TASK_SELF_CONNECT,     ///< Perform a self connection.
         TASK_REP_SELF_CONNECT  ///< Perform repeated self connections.
      };
      
      
      
      /**
       * 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.
       *
       * @throw 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 the first of two phone numbers. Where
       * supported this is the destination phone number, the second is the
       * optional source phone number.
       *
       * The options for the main tasks are mutually exclusive. Only one of them
       * may be specified on the command line. If none or more than one are
       * given, an error will be returned.
       *
       * @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 "-l",
       *                        "-i", "-{oO}", "-{bB}" nor "-{sS}" 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_*         The respective task shall be executed.
       */
      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);
      
      /**
       * Get setting for verbose output.
       */
      bool GetVerboseOutput (void);
      
      /**
       * Get setting for the addressed controller.
       */
      unsigned GetController (void);
      
      /**
       * Get the setting to use all controllers.
       */
      bool GetUseAllControllers (void);
      
      /**
       * Get the requested connection type.
       */
      CCapiStateMachine::ConnectionType_t GetConnectionType (void);
      
      /**
       * Get the requested number of concurrent calls.
       */
      size_t GetNumCalls (void);
      
      /**
       * Get the setting to send user-user data.
       */
      bool GetSendUUData (void);
      
      /**
       * Get the setting to echo all incoming data.
       */
      bool GetEchoData (void);
      
      /**
       * Get the output file name.
       */
      const std::string &GetOutputFileName (void);
      
      /**
       * Get the batch file name.
       */
      const std::string &GetBatchFileName (void);
      
      /**
       * Get the input file name pattern.
       */
      const std::string &GetInputFileNamePattern (void);
      
      /**
       * Get the destination phone number.
       */
      const std::string &GetDstPhoneNumber (void);
      
      /**
       * Get the source phone number.
       */
      const std::string &GetSrcPhoneNumber (void);
      


   protected:



   private:
      /// The short program file name.
      std::string m_strProgName;
      
      /// The command line evaluator object.
      thwutil::CCmdLineEvaluator m_cmdLineEvaluator;
      
      /// The option object for the task "controller list".
      thwutil::CBooleanCmdOpt m_cmdOptListCtlr;
      
      /// The option object for the task "incoming calls".
      thwutil::CBooleanCmdOpt m_cmdOptInCalls;
      
      /// The option object for the task "fixed no. outgoing calls".
      thwutil::CStringParamCmdOpt m_cmdOptOutCalls;
      
      /// The option object for the task "repeated no. outgoing calls".
      thwutil::CStringParamCmdOpt m_cmdOptRepOutCalls;
      
      /// The option object for the task "batch of outgoing calls".
      thwutil::CStringParamCmdOpt m_cmdOptBatchCalls;
      
      /// The option object for the task "repeated batch of outgoing calls".
      thwutil::CStringParamCmdOpt m_cmdOptRepBatchCalls;
      
      /// The option object for the task "self connection".
      thwutil::CBooleanCmdOpt m_cmdOptSelfConnect;
      
      /// The option object for the task "repeated self connection".
      thwutil::CBooleanCmdOpt m_cmdOptRepSelfConnect;
      
      /// The option object for verbose output of some tasks.
      thwutil::CBooleanCmdOpt m_cmdOptVerbose;
      
      /// The option object for the addressed controller.
      thwutil::CUIntParamCmdOpt m_cmdOptCtlr;
      
      /// The option object to handle all controllers for incoming calls.
      thwutil::CBooleanCmdOpt m_cmdOptAllControllers;
      
      /// The option object for the type of the call(s).
      thwutil::CEnumStringParamCmdOpt m_cmdOptCallType;
      
      /// The option object for the (fixed) number of calls.
      thwutil::CUIntParamCmdOpt m_cmdOptNumCalls;
      
      /// The option object for sending connection type and checksum data as
      /// user-user data.
      thwutil::CBooleanCmdOpt m_cmdOptSendChecksumData;
      
      /// The option object for echoing all incoming data.
      thwutil::CBooleanCmdOpt m_cmdOptEchoData;
      
      /// The option object for the file name pattern to store incoming data.
      thwutil::CStringParamCmdOpt m_cmdOptInputFileNamePattern;
      
      /// The option object for help output by "-h".
      thwutil::CBooleanCmdOpt m_cmdOptHelp1;
      
      /// The option object for help output by "-?".
      thwutil::CBooleanCmdOpt m_cmdOptHelp2;

      /// The main task to execute (after command line evaluation).
      TaskToExecute_t m_mainTask;
      
      /// Flag for verbose output for some tasks.
      bool m_fVerboseOutput;
      
      /// The controller to use for most tasks.
      unsigned m_uController;

      /// Flag to handle all controllers, not only one.
      /// This is only useful for incoming connections.
      bool m_fUseAllControllers;
      
      /// The type of call to be made (really of type
      /// CCapiStateMachine::ConnectionType_t).
      int m_iCallType;

      /// The number of concurrent calls for some tasks.
      unsigned m_uNumCalls;

      /// Flag to send out checksum data as user-user data for outgoing calls.
      bool m_fSendUUData;
      
      /// Flag to echo all incoming data.
      bool m_fEchoData;
      
      /// The name of the file with data to send for outgoing calls.
      std::string m_strOutputFileName;
      
      /// The name of the batch file for batch calls.
      std::string m_strBatchFileName;
      
      /// The file name pattern to store data for incoming calls.
      std::string m_strInputFileNamePattern;
      
      /// The destination phone number for some tasks.
      std::string m_strDstPhoneNumber;
      
      /// The source phone number for some tasks.
      std::string m_strSrcPhoneNumber;
      


}; // CConfig





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





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





#endif // __CONFIG_H
