/**<
 * \file BGDNetContext.cpp
 * \brief Реализация класса Context
 */

#include "BGDNetPch.h"

#include "BGDNetContext.h"

#include <nwerror.h>

namespace BGDNet
{

Context::Context( void )
  throw(Exception)
{
  create();
}

Context::Context( const char* ctxName )
  throw(Exception)
{
  create();
  name(ctxName);
}

Context::Context( const Context& ctx )
  throw(Exception)
{
  NWDSCCODE err = NWDSDuplicateContextHandle(ctx, &m_handle);
  if (err)
    throw Exception(err);
}

Context::~Context( void )
{
  NWDSFreeContext(m_handle);
}

Context::operator NWDSContextHandle( void ) const
{
  return m_handle;
}

void Context::name( const char* name )
{
  NWRCODE err = NWDSSetContext(
    m_handle,
    DCK_NAME_CONTEXT,
    const_cast<char*>(name + 1));
  if (err)
    throw Exception(err);
}

String Context::name( void ) const
{
  char buf[MAX_DN_CHARS + 1];
  NWRCODE err = NWDSGetContext(m_handle, DCK_NAME_CONTEXT, buf);
  if (err)
    throw Exception(err);
  return String(buf);
}

void Context::dsiFlags( nuint32 flags )
{
  NWRCODE err = NWDSSetContext(m_handle, DCK_DSI_FLAGS, &flags);
  if (err)
    throw Exception(err);
}

nuint32 Context::dsiFlags( void ) const
{
  nuint32 flags = 0;
  NWRCODE err = NWDSGetContext(m_handle, DCK_DSI_FLAGS, &flags);
  if (err)
    throw Exception(err);
  return flags;
}

void Context::dckFlags( nuint32 flags )
{
  NWRCODE err = NWDSSetContext(m_handle, DCK_FLAGS, &flags);
  if (err)
    throw Exception(err);
}

nuint32 Context::dckFlags( void ) const
{
  nuint32 flags = 0;
  NWRCODE err = NWDSGetContext(m_handle, DCK_FLAGS, &flags);
  if (err)
    throw Exception(err);
  return flags;
}

String Context::dn( const char* name ) const
{
  char bufFq[MAX_DN_CHARS + 1];
  char bufTypeless[MAX_DN_CHARS + 1];
  
  // Приводим имя к "канонической" форме:
  NWRCODE err = NWDSCanonicalizeName(
    m_handle,
    const_cast<char*>(name),
    bufFq);
  if (err)
    throw Exception(err);
  
  // Убираем из имени типы, т.к. NWDSCanonicalizeName все равно
  // не может гарантировать их корректность:
  err = NWDSRemoveAllTypes(m_handle, bufFq, bufTypeless);
  if (err)
    throw Exception(err);
  
  // Полное начинается с точки:
  String s = ".";
  s += bufTypeless;
  return s;
}

String Context::rdn( const char* name ) const
{
  char buf[MAX_RDN_CHARS + 1];
  NWDSCCODE err = NWDSAbbreviateName(
    m_handle,
    const_cast<char*>(name),
    buf);
  if (SUCCESS != err)
    throw Exception(err);
  return String(buf);
}

void Context::create( void )
{
  NWRCODE err = NWDSCreateContextHandle(&m_handle);
  if (err)
    throw Exception(err);
}

} // namespace BGDNet
