/**
 * \file BGDNetServer.cpp
 * \brief Реализация классов Server и Servers
 */

#include "BGDNetPch.h"

#include "BGDNetServer.h"

#include <nwvol.h>
#include <nwerror.h>
#include "BGDNetVolume.h"
#include "BGDNetConnection.h"
#include "BGDNetContext.h"

#ifdef BGDNET_USE_MFC
# ifdef _DEBUG
#   define new DEBUG_NEW
#   undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
# endif
#endif

namespace BGDNet
{

Server::Server( ConnRef ref )
  throw(Exception) :
  m_connRef(ref)
{
  char buf[NW_MAX_SERVER_NAME_LEN];
  memset(buf, 0, sizeof(buf));
  NWRCODE err = NWCCGetConnRefInfo(
    m_connRef,
    NWCC_INFO_SERVER_NAME,
    sizeof(buf),
    buf);
  if (SUCCESS != err)
    throw Exception(err);
  m_srvName = buf;
}

Server::Server( const String& srvName )
  throw(Exception)
{
  Connection conn(srvName);
  m_connRef = conn.ref();
  m_srvName = srvName;
}

void Server::getVolumes( Volumes* pColl ) const
  throw(Exception)
{
  pColl->clear();

  // Будем считать, что больше 256 томов не будет ;-)
  const int MAX_VOLUMES = 256;
  NWVolMountNumWithName buf[MAX_VOLUMES];
  
  // Получаем список имен томов:
  nuint32 iterHandle = 0;
  nuint32 numReturned = 0;
  NWCCODE err = NWScanMountedVolumeList(
    Connection(m_connRef),
    NW_VOLUME_NUMBER_AND_NAME,
    NW_NS_DOS,
    &iterHandle,
    256,
    &numReturned,
    buf);
  if (SUCCESS != err)
    throw Exception(err);
  
  // Заполняем коллекцию:
  for (int i = 0; i < numReturned; ++i)
    pColl->add(new Volume(this, buf[i].volumeName));
}

ConnRef Server::connRef( void ) const
{
  return m_connRef;
}

const String& Server::name( void ) const
{
  return m_srvName;
}

String Server::objNameById( nuint32 objId, const Context& ctx ) const
  throw(Exception)
{
  char buf[MAX_DN_CHARS + 1];
  NWRCODE err = NWDSMapIDToName(
    ctx,
    Connection(m_connRef),
    objId,
    buf);
  if (err)
    throw Exception(err);
  return String(buf);
}

nuint32 Server::objIdByName( const char* objName, const Context& ctx ) const
  throw(Exception)
{
  nuint32 id;
  NWRCODE err = NWDSMapNameToID(
    ctx,
    Connection(m_connRef),
    (pnstr8)objName,
    &id);
  if (err)
    throw Exception(err);
  return id;
}




Servers::Servers( void )
  throw(Exception)
{
  nuint32 scanIterator = 0;
  nuint32 ref;
  for (;;)
  {
    // Получаем ссылку на очередное соединение:
    NWRCODE err = NWCCScanConnRefs(&scanIterator, &ref);
    if (NWE_NO_MORE_ENTRIES == err)
      break; // соединений больше нет!
    else if (SUCCESS != err)
      throw Exception(err);
    
    // Добавляем элемент в коллекцию:
    m_servers.add(new Server(ConnRef(ref)));
  }
}

int Servers::count( void ) const
{
  return m_servers.size();
}

Server* Servers::operator []( int n )
{
  return m_servers[n];
}

const Server* Servers::operator []( int n ) const
{
  return m_servers[n];
}

} // namespace BGDNet
