//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / 
//
//File: mibobject.h
//
//Version: $Revision: 1.30 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/10/19 18:16:53 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author:
//      Sami Raatikainen
//
//Description:
//      Classes for different kind of objects in a MIB.
//      Almost all methods may throw an mibException with
//      error codes defined in RFC1157.
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//
//
//History: 

#ifndef __MIB_MIBOBJECT_H__
#define __MIB_MIBOBJECT_H__

class VarBind;
class mibColumn;

#include <typeinfo>
#include <string>
#include <map>
#include "mibdestination.h"
#include "convert.h"
#include "protocol/ilmi/asn/asnutil.h"


//
//Class: mibObject
//
//Description:
//      Base class. Offers common interface and default methods for
//      inherited classes, and static methods to create different mibObjects.
//

class mibObject
{
    public:
        virtual ~mibObject(void);

        virtual bool isNode(void) const;
        virtual bool isTable(void) const;
        
        // create-methods
        static mibObject *createNode(void);
        static mibObject *createTable(void);
        static mibObject *createAsnIntColumn(const string & objectID_,
                                             mibDestination *dest_);
        static mibObject *createAsnOctsColumn(const string & objectID_,
                                              mibDestination *dest_);
        static mibObject *createAsnOidColumn(const string & objectID_,
                                             mibDestination *dest_);
        static mibObject *createAsnIntLeaf(const string & objectID_,
                                           mibDestination *dest_,
                                           bool writeAccess_);
        static mibObject *createAsnOctsLeaf(const string & objectID_,
                                            mibDestination *dest_,
                                            bool writeAccess_);
        static mibObject *createAsnOidLeaf(const string & objectID_,
                                            mibDestination *dest_,
                                            bool writeAccess_);

        // method to get the requested object (get/setRequest)
        virtual mibObject *get(asnUtil::oidList &constOidIter_) const;

        // methods needed for the getNextRequest
        virtual bool getNext(asnUtil::oidList &oidList_,
                                  VarBind *varBind_) const;
        virtual bool getFirstInstance(VarBind *varBind_) const;
        
        // methods to send requests over CORBA w/ type converting
        virtual void getValue(VarBind *varBind_) const;
        virtual void setValue(VarBind *varBind_) const;

        // methods to convert strings to different AsnTypes and vice versa
        virtual void stringToVarBind(VarBind *varBind_,
                                     const string &svalue_,
                                     asnUtil::oidList &oidList_) const;
        virtual void varBindToString(VarBind *varBind_,
                                     string &svalue_,
                                     asnUtil::oidList &oidList_) const;

        // adds new object under the current object
        virtual void add(pfUlong key_, mibObject *newObject_);

    protected:
        mibObject(void);
};

//
//Class: mibNode
//
//Description:
//      Represents a node in a tree.
//      May have nodes, tables and leafs under it.
//

class mibNode : public mibObject
{
    public:
        mibNode(void);
        virtual ~mibNode(void);
        virtual bool isNode(void) const;

        mibObject *get(asnUtil::oidList &oidList_) const;
        bool getNext(asnUtil::oidList &oidList_, VarBind *varBind_) const;
        bool getFirstInstance(VarBind *varBind_) const;

        void add(pfUlong key_, mibObject *newObject_);

    private:
        typedef map<pfUlong, mibObject*, less<pfUlong> > objMapType;
        typedef objMapType::const_iterator objIterator;
        objMapType _objectMap;
};


//
//Class: mibTable
//
//Description:
//      Has a map for columns and another for rowindexes (object IDs).
//      Doesn't add rows with set-request, only passes the request through
//      to the correct destination using mibColumn-object for asnType-
//      string translations.
//

class mibTable : public mibObject
{
    public:
        mibTable(void);
        virtual ~mibTable(void);
        bool isTable(void) const;

        mibObject *get(asnUtil::oidList &oidList_) const;
        bool getNext(asnUtil::oidList &oidList_, VarBind *varBind_) const;
        bool getFirstInstance(VarBind *varBind_) const;

        void getValue(VarBind *varBind_, asnUtil::oidList &oidList_) const;
        void setValue(VarBind *varBind_, asnUtil::oidList &oidList_) const;
        
        void stringToVarBind(VarBind *varBind_,
                             const string &svalue_,
                             asnUtil::oidList &oidList_) const;
        void varBindToString(VarBind *varBind_,
                             string &svalue_,
                             asnUtil::oidList &oidList_) const;
                             
        void add(pfUlong key_, mibObject *newObject_);
        void addRow(const string &index_);
        void clear(void);
        void deleteRow(const string &index_);

    private:
        typedef map<pfUlong, mibColumn*, less<pfUlong> > colMapType;
        typedef colMapType::const_iterator colIterator;
        colMapType _colMap;

        typedef map<string, bool, less<string> > rowMapType;
        typedef rowMapType::const_iterator rowIterator;
        rowMapType _rowMap;

        void checkOid(const asnUtil::oidList &oidList_) const;
        void popOidFromList(asnUtil::oidList &oidList_) const;
        mibObject *getColumn(asnUtil::oidList &oidList_) const;
};

//
//Class: mibColumn
//
//Description:
//      Column for mibTables. Has interface (mibDestination) to get/set
//      values, to which a pointer will be given at the constructor.
//      Also has a pointer to a specified convert class to encode
//      different kind of AsnTypes to strings and vice versa.
//

class mibColumn : public mibObject
{
    private:
        string _stringOid;
        mibDestination *_destination;
        convert *_convert;
        
    public:
        mibColumn(const string &objectID_,
                  mibDestination *_destination,
                  convert *convert_);
        virtual ~mibColumn(void);

        void getRow(VarBind *varBind_, const string &rowID_) const;
        
        void getValue(VarBind *varBind_) const;
        void setValue(VarBind *varBind_) const;
        
        void stringToVarBind(VarBind *varBind_,
                             const string &svalue_,
                             asnUtil::oidList &oidList_) const;
        void varBindToString(VarBind *varBind_,
                             string &svalue_,
                             asnUtil::oidList &oidList_) const;
};

//
//Class: mibLeaf
//
//Description:
//      Has interface (mibDestination) to get/set values, to which
//      a pointer will be given at the constructor. Also has a pointer
//      to a specified convert class to encode different kind of
//      AsnTypes to strings and vice versa. WriteAccess-variable
//      (given at the constructor) defines if user may call setValue-method
//      from mibDestination.
//

class mibLeaf : public mibObject
{
    private:
        string _stringOid;
        mibDestination *_destination;
        convert *_convert;
        bool _writeAccess;

    public:
        mibLeaf(const string &objectID_,
                mibDestination *destination_,
                convert *convert_,
                bool writeAccess_);
        virtual ~mibLeaf(void);
        
        mibObject *get(asnUtil::oidList &oidList_) const;
        bool getFirstInstance(VarBind *varBind_) const;
        
        void getValue(VarBind *varBind_) const;
        void setValue(VarBind *varBind_) const;
        
        void stringToVarBind(VarBind *varBind_,
                             const string &svalue_,
                             asnUtil::oidList &) const;
        void varBindToString(VarBind *varBind_,
                             string &svalue_,
                             asnUtil::oidList &) const;
};

#endif // __MIB_MIBOBJECT_H__
