/*!
  \file    DBMSrvCmd_Command.hpp
  \author  MarcW
  \ingroup common classes for the DBMServer
  \brief   declaration of base class for DBMServer commands

\if EMIT_LICENCE

    ========== licence begin  GPL
    Copyright (c) 2002-2005 SAP AG

    This program 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
    of the License, or (at your option) any later version.

    This program 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 this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end


\endif
*/

#ifndef _DBMSrv_Command_HPP_
#define _DBMSrv_Command_HPP_


#include "gcn00.h"
#include "gcn002.h"

#include "DBM/Srv/DBMSrv_Reply.hpp"


/*!
    @brief base class for DBMServer commands

    All DBMServer commands should be derived from this one. At the moment, command
    execution, printing of command syntax and command explanation is possible. In
    the future, more tasks e.g. parameter checking should be moved into this
    class. The array in vcn10.cpp should then only contain a mapping of
    command strings entered by user and command keys, defined here (or that
    array should disappear all together).
    @see DBMSrv_Command::CommandKey
*/
class DBMSrv_Command {
public:
    /*!
        @brief the command keys

        Each command has its unique key.
    */
    enum CommandKey {
        KeyBackupHistoryAppend,                 /*!< key for command class DBMSrvCmdBHist_BackupHistoryAppend */
        KeyDbmExecuteServerprocess,             /*!< handled in DBMSrvCmd_DbmExecuteServerprocess */
        KeyDbmVersion,                          /*!< handled in DBMSrvCmd_DbmVersion         */
        KeyHelp,                                /*!< key for command class DBMSrvCmd_Help */
        KeyHssCopyFile,                         /*!< handled in DBMSrvCmd_HssCopyFile        */
        KeyInstInfo,                            /*!< handled in DBMSrvCmd_InstInfo           */
        KeyMediumDelete,                        /*!< key for command class DBMSrvCmdMedium_MediumDelete */
        KeyMediumDeleteNoDistribute,            /*!< key for command class DBMSrvCmdMedium_MediumDeleteNoDistrib */
        KeyMediumPut,                           /*!< key for command class DBMSrvCmdMedium_MediumPut */
        KeyMediumPutNoDistribute,               /*!< key for command class DBMSrvCmdMedium_MediumPutNoDistrib */
        KeySqlUpdatestatPerSystemtable,         /*!< key for command class DBMSrvCmdSQL_SqlUpdatestatPerSystemtable */
        KeyUnknownCommand                       /*!< the unknown command, no implementation! */
    }; 

    /* \brief dispatching stuff
    
       get a command object for the command key 
       \param aCommandKey [IN] the key for the searched command object
       \param theReply    [IN] reply object holding the reply buffer
       \return pointer to a object representing the command, 0 if error occured */
    static DBMSrv_Command* getCommand(
                CommandKey     aCommandKey,
                DBMSrv_Reply & theReply);

    // constructor
    DBMSrv_Command( CommandKey commandKey, bool isObsolete, const char * longHelp=0, bool isHidden=false )
        : m_isObsolete(isObsolete),
          m_isHidden(isHidden),
          m_longHelp(longHelp),
          m_RundirectoryNotCalculated(true),
          m_UnicodeNotCalculated(true),
          m_InstanceTypeNotCalculated(true),
          m_commandKey(commandKey) {
        m_Rundirectory.Init();
        m_Unicode.Init();
        m_InstanceType.Init();
    }

    virtual ~DBMSrv_Command() {}

    // base class stuff
    /*! function representing the wish of the command to be an obsolete command
        in the DBM Server command help. The help command should honor this wish.
        \return true, if the DBM server command is an osolete command, false otherwise */
    bool isObsolete() { return m_isObsolete;}
    /*! function representing the wish of the command to be hidden by the DBM Server command help
        \return true, if the DBM server command should be hidden, false otherwise */
    bool isHidden() { return m_isHidden;}
    CommandKey getCommandKey() { return m_commandKey;}

    virtual bool getExplainText(CommandT* command, DBMSrv_Reply& theReply);
    virtual bool getSyntaxText(DBMSrv_Reply& theReply);
    virtual bool getUsageText(DBMSrv_Reply& theReply);

    /*! \brief the virtual function implementing the command
        (you have to overload this function in order to implement a new command) */
    virtual tcn00_Error run(
                    VControlDataT* vcontrol,
                    CommandT* command,
                    DBMSrv_Reply& theReply) = 0;

    /*! \brief static function providing the run function of a command for vcn10.cpp
        \TODO should be eliminated together with vcn10.cpp in the long run */
    static tcn00_Error runCommand
        (VControlDataT * vcontrol,
         CommandT      * command,
         char          * replyData,
         int           * replyLen,
         int             replyLenMax);

protected:
    // members
    CommandKey   m_commandKey;
    bool         m_isObsolete;
    bool         m_isHidden;   //!< true if command would like to be hidden in the output of the help command
    const char * m_longHelp;

    // helpers
    const char* getRundirectory(bool ReadAgain = false);
    const char* getUnicode     (bool ReadAgain = false);
    const char* getInstanceType(bool ReadAgain = false);

    static void formatExplainText(CommandT* command, DBMSrv_Reply& theReply, const char* longHelp);
    static void formatSyntaxText(DBMSrv_Reply& theReply, const char* longHelp);

private:
    bool getParameter   (const char * szName, tcn002_XpValueString & oValue);

    bool m_RundirectoryNotCalculated;
    tcn002_XpValueString m_Rundirectory;
    bool m_UnicodeNotCalculated;
    tcn002_XpValueString m_Unicode;
    bool m_InstanceTypeNotCalculated;
    tcn002_XpValueString m_InstanceType;
};
#endif //_DBMSrv_Cmd_HPP_

