/*!
 * \file    OMS_Globals.hpp
 * \author  MarkusSi, PeterG
 * \brief   Global methods and variables.
 */
/*

    ========== 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

*/

#ifndef __OMS_GLOBALS_HPP
#define __OMS_GLOBALS_HPP

#include "Oms/OMS_SharedMemAllocator.hpp"
#include "Oms/OMS_Oid.hpp"
#include "Oms/OMS_LibOmsInterfaceInstance.hpp"
#include "liveCache/LVC_KernelInterface.hpp"
#include "ggg250.h"
#include "Oms/OMS_VersionDictionary.hpp"
#include "Oms/OMS_DynamicStack.hpp"  // PTS 1129082


// PTS 1117690
// This size must equals half the size of the array in the procedure calls  
// in the AK layer and the definition of the array 'tak_oms_version_desc'  
// in vak001. The desciption is always stored in UCS2-format (2 bytes per 
// character, while the array size is given in bytes.
#define OMS_MAX_VERSION_DESC_LENGTH 256


/*!
**  Class is needed to buffer the information of entries in the version directory.
**  PTS 1129082
*/
class VersionEntry {
public:
  OmsVersionId       versionId;
  tsp00_Date         createDate;
  tsp00_Time         createTime;
  tsp00_Date         openDate;
  tsp00_Time         openTime;
  tgg91_TransNo      consistentView;
  tsp00_Bool         isMarked;
  tsp00_Bool         isOpen;
  tsp00_Bool         isUnloaded;
  tsp00_8ByteCounter heapUsage;
  tsp00_Int4         hashSize;
  tgg00_FileId       versionTree;
  tgg00_FileId       versionInvTree;
  tsp00_Bool         hasVersionDesc;
  OmsTypeWyde        versionDesc[OMS_MAX_VERSION_DESC_LENGTH];
};



#define OMS_DATA_ALIGNMENT  sizeof(void*)

class DbpError;
class OMS_DumpInterface;
class OMS_TraceInterface;
class OMS_VersionDictionary;
class OMS_ContainerDictionary;
class OMS_Context;
class OMS_ContainerInfo;
class OMS_ClassInfo;
class OMS_MonitorDirectory;
class OMS_ContainerDictionaryIterator;

class OMS_ResetSink {
public :
  OMS_ResetSink() {}
  inline ~OMS_ResetSink();
};

class OMS_ActionOnError {
public:
  tsp00_Int4  errorNo;
  bool        dump;
  bool        stop;
  bool        flush;
};

typedef IliveCacheSink* (*OMS_GetSinkPtrFunc)(void);

class OMS_Globals {
private:
  OMS_Globals();
  ~OMS_Globals() 
  {
  }
public:
  static void InitSingletons();

  void Dump(OMS_DumpInterface& dumpObj);
  bool ActionOnError(tsp00_Int4 errorNo, bool &dump, bool &stop, bool &flush);
  void DumpVersionDirectory(OMS_DumpInterface& dumpObj);
  bool InSimulator() const;
  bool IsOmsTestLib() const { return m_isOmsTestLib;}
  void SetDumpError(tsp00_Int4, OMS_DiagnoseAction);
  void SetHost(bool isKernel);
  void SetOmsVersionThreshold(tsp00_Uint4 threshold); /* PTS 1110149 */
  tsp00_Uint4 GetOmsVersionThreshold() const          /* PTS 1110149 */
  {
    return m_omsVersionThreshold;
  }
  OMS_TraceInterface* GetTracer();
  void SetTracer(OMS_TraceInterface* pTraceObj);
  void ResetInfo();
  int GetLockIdForVersionDirectory (const OmsVersionId &versionId) const; // PTS 1124170
  bool GetLockMethodForVersionDictionary() const;                         // PTS 1124170
  static IliveCacheSink* GetCurrentLcSink();
  static void Throw(const DbpError& e);
  static void MakeKnlIdentifier (const char* Source, tsp00_KnlIdentifier& Dest);
  static inline size_t AlignSize(size_t val)
  {
    return ((val + (OMS_DATA_ALIGNMENT - 1)) & ~(OMS_DATA_ALIGNMENT - 1)); 
  }

  /*----------------------------------------------------------------------*/


  //
  // caution : order of member variables is important !!
  //

  OMS_VersionDictionary      &m_versionDictionary;
  OMS_ContainerDictionary    &m_classDictionary;
  OMS_MonitorDirectory       &m_monitorDirectory;
  // global container iterator
  OMS_ContainerDictionaryIterator	&ContainerIter;
  // global version iterator, used for 'select .. from sysdd.oms_versions
  OMS_VersionDictionary::Iter m_versionIter;
  /*! The versionBuffer is used while iteration over the version directory. 
  ** All information belonging to versions which are synchronized via
  ** the same region are stored in the buffer. After having stored the 
  ** information the region can be freed and so contention on the locks
  ** should be prevented. If the iterator has read all information from the
  ** buffer, the versions which belong to the next region are filled in the
  ** buffer, ...
  ** \since PTS 1129082
  */
  OMS_DynamicStack<VersionEntry,OMS_SharedMemAllocator>  m_versionBuffer;

private:
  enum { MAX_DUMP_ERRORS = 64 };
  enum LibHost
  {
    HostUnknown,
    HostKernel,
    HostSimulator,
  };
  bool               m_isOmsTestLib;
  LibHost            m_host;
  int                m_cntDumpErrors;
  int                m_heapThreshold;       /* PTS 1110149 */
  tsp00_Uint4        m_omsVersionThreshold; /* PTS 1110149 */
  OMS_TraceInterface *m_tracer;
  OMS_ActionOnError  m_actionOnError[MAX_DUMP_ERRORS];

  // m_resetSink must be last member, because the destructor ensures, that the
  // destructors of the other members don't ask for the kernel environment !
  OMS_ResetSink       m_resetSink;

public:
  static OMS_SharedMemAllocator m_sharedMemAllocatorInstance;

  static LVC_KernelInterface* KernelInterfaceInstance;
  static OMS_LibOmsInterfaceInstance *m_libOmsInterfaceInstance;
  static OMS_GetSinkPtrFunc   GetSinkAddrFunc;
  static OMS_ContainerInfo* FindContainerInfo(IliveCacheSink* lcSink, tsp00_Uint4 containerInfo);
  static OMS_ContainerInfo* FindContainerInfo(IliveCacheSink* lcSink, const ClassIDRef guid, OmsSchemaHandle, OmsContainerNo);
  static OMS_ClassInfo* FindClassInfo(IliveCacheSink* lcSink, const ClassIDRef guid);
  static void DetachContainerInfo(IliveCacheSink*, OMS_ContainerInfo*);


  inline static tsp00_Int4 Min(tsp00_Int4 t1, tsp00_Int4 t2) 
  {
    if (t1 < t2) 
      return t1;
    else
      return t2;
  }

  inline static tsp00_Int4 Max(tsp00_Int4 t1, tsp00_Int4 t2) 
  {
    if (t1 > t2) 
      return t1;
    else
      return t2;
  }

  inline static LVC_KernelInterface* GetKernelInterface()
  {
    if (KernelInterfaceInstance == NULL)
      OMS_Globals::InitSingletons();
    return KernelInterfaceInstance;
  }

  static int WideStrlen(const OmsTypeWyde* s);

  OmsObjectId    m_nilOid;
  tgg91_PageRef  m_nilSeq;

  static OMS_Globals *m_globalsInstance;
};

IliveCacheSink *OMS_GetProxySinkAddr();

inline OMS_ResetSink::~OMS_ResetSink()
{
  if (NULL != OMS_Globals::KernelInterfaceInstance)
  {
    OMS_Globals::KernelInterfaceInstance->SignalUnloadLiboms();
  }
  OMS_Globals::GetSinkAddrFunc = OMS_GetProxySinkAddr;
}

/*----------------------------------------------------------------------*/
/* PTS 1115231 */
extern bool omsIsUnicodeInstance();

/*----------------------------------------------------------------------*/
/* PTS 1135956 */
extern bool omsIsOneDBSystem();

/*----------------------------------------------------------------------*/

extern void omsSimConsoleMessage(const char*);

/*----------------------------------------------------------------------*/

extern void omsGetLiveCacheVersion(char *pBuf, int bufSize);


/*----------------------------------------------------------------------*/
/* Compatibility stuff for SQL class, it will go away:                  */
/*----------------------------------------------------------------------*/

inline static LVC_KernelInterface* co10_GetKernelInterface()
{
  if (OMS_Globals::KernelInterfaceInstance == NULL) OMS_Globals::InitSingletons();
  return OMS_Globals::KernelInterfaceInstance;
}

/*----------------------------------------------------------------------*/

inline static IliveCacheSink* co10_GetLcSink()
{
  return OMS_Globals::KernelInterfaceInstance->GetSinkPtr();
}


#endif  // __OMS_GLOBALS_HPP
