/**
 * \file BGDNetFile.cpp
 * \brief Реализация класса File
 */

#include "BGDNetPch.h"

#include "BGDNetFile.h"

#include "BGDNetDirectory.h"
#include "BGDNetConnection.h"
#include "BGDNetVolume.h"
#include "BGDNetServer.h"

namespace BGDNet
{

File::File( const Volume* pVol, const Path& relPath )
  throw(Exception) :
  DirEntry(pVol, relPath)
{
}

File::File( const Directory* pDir, const Path& fileName )
  throw(Exception) :
  DirEntry(pDir->vol(), pDir->relPath())
{
  // Необходимо учесть, что в общем случае родительский каталог и имя
  // файла могут быть заданы в различных пространствах имен.
  // Поэтому необходимо узнать имя файла в пространстве имен,
  // соответствующем родительскому каталогу:
  Connection conn(vol()->srv()->connRef());
  DirHandle dirHandle(vol(), relPath(), fileName.ns());
  NW_ENTRY_INFO info;
  NWCCODE err = NWGetNSEntryInfo(
    conn,
    dirHandle,
    fileName,
    fileName.ns(),
    relPath().ns(),
    SA_ALL,
    IM_ENTRY_NAME,
    &info);
  if (SUCCESS != err)
    throw Exception(err);

  // На текущий момент относительный путь содержит путь к родительскому
  // каталогу. Необходимо добавить к нему полученное имя файла:
  relPath() += '\\';
  relPath() += info.entryName;
}

nuint32 File::ownerId( void ) const
{
  NWENTRY_INFO info;
  getEntryInfo(FA_HIDDEN | FA_SYSTEM | FA_NORMAL, &info);
  return info.ownerID;
}

void File::ownerId( nuint32 id )
{
  NWENTRY_INFO info;
  memset(&info, 0, sizeof(info));
  info.ownerID = id;
  setEntryInfo(
    FA_HIDDEN | FA_SYSTEM | FA_NORMAL,
    info,
    MOwnerIDBit);
}

nuint32 File::modifierId( void ) const
{
  NWENTRY_INFO info;
  getEntryInfo(FA_HIDDEN | FA_SYSTEM | FA_NORMAL, &info);
  return info.info.file.updatorID;
}

void File::modifierId( nuint32 id )
{
  NWENTRY_INFO info;
  memset(&info, 0, sizeof(info));
  info.info.file.updatorID = id;
  setEntryInfo(
    FA_HIDDEN | FA_SYSTEM | FA_NORMAL,
    info,
    MLastUpdatedIDBit);
}

String File::modifierName( const Context& ctx ) const
{
  return vol()->srv()->objNameById(modifierId(), ctx);
}

void File::modifierName( const Context& ctx, const char* name )
{
  modifierId(vol()->srv()->objIdByName(name, ctx));
}

nuint32 File::size( void ) const
{
  NWENTRY_INFO info;
  getEntryInfo(FA_HIDDEN | FA_SYSTEM | FA_NORMAL, &info);
  return info.info.file.fileSize;
}

} // namespace BGDNet
