// UpdateCallback.cpp

#include "StdAfx.h"

#include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/Wildcard.h"

#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileName.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Windows/Synchronization.h"

#include "../../Common/FileStreams.h"
#include "../../Common/StreamObjects.h"

#include "UpdateCallback.h"

#if defined(_WIN32) && !defined(UNDER_CE)
#define _USE_SECURITY_CODE
#include "../../../Windows/SecurityUtils.h"
#endif

using namespace NWindows;
using namespace NFile;

#ifdef _USE_SECURITY_CODE
bool InitLocalPrivileges();
#endif

CArchiveUpdateCallback::CArchiveUpdateCallback():
  Callback(0),
  ShareForWrite(false),
  StdInMode(false),
  DirItems(0),
  ArcItems(0),
  UpdatePairs(0),
  NewNames(0),
  KeepOriginalItemNames(false),
  ProcessedItemsStatuses(NULL),
  ParentDirItem(NULL),
  StoreNtSecurity(false),
  StoreHardLinks(false),
  StoreSymLinks(false),
  _hardIndex_From((UInt32)(Int32)-1)
{
  #ifdef _USE_SECURITY_CODE
  _saclEnabled = InitLocalPrivileges();
  #endif
}


STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
{
  COM_TRY_BEGIN
  return Callback->SetTotal(size);
  COM_TRY_END
}

STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)
{
  COM_TRY_BEGIN
  return Callback->SetCompleted(completeValue);
  COM_TRY_END
}

STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
{
  COM_TRY_BEGIN
  return Callback->SetRatioInfo(inSize, outSize);
  COM_TRY_END
}


/*
static const STATPROPSTG kProps[] =
{
  { NULL, kpidPath, VT_BSTR},
  { NULL, kpidIsDir, VT_BOOL},
  { NULL, kpidSize, VT_UI8},
  { NULL, kpidCTime, VT_FILETIME},
  { NULL, kpidATime, VT_FILETIME},
  { NULL, kpidMTime, VT_FILETIME},
  { NULL, kpidAttrib, VT_UI4},
  { NULL, kpidIsAnti, VT_BOOL}
};

STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
{
  return CStatPropEnumerator::CreateEnumerator(kProps, ARRAY_SIZE(kProps), enumerator);
}
*/

STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
      Int32 *newData, Int32 *newProps, UInt32 *indexInArchive)
{
  COM_TRY_BEGIN
  RINOK(Callback->CheckBreak());
  const CUpdatePair2 &up = (*UpdatePairs)[index];
  if (newData) *newData = BoolToInt(up.NewData);
  if (newProps) *newProps = BoolToInt(up.NewProps);
  if (indexInArchive)
  {
    *indexInArchive = (UInt32)(Int32)-1;
    if (up.ExistInArchive())
      *indexInArchive = (ArcItems == 0) ? up.ArcIndex : (*ArcItems)[up.ArcIndex].IndexInServer;
  }
  return S_OK;
  COM_TRY_END
}

STDMETHODIMP CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *value)
{
  NCOM::CPropVariant prop;
  switch (propID)
  {
    case kpidIsDir:  prop = true; break;
    case kpidAttrib: if (ParentDirItem) prop = ParentDirItem->Attrib; break;
    case kpidCTime:  if (ParentDirItem) prop = ParentDirItem->CTime; break;
    case kpidATime:  if (ParentDirItem) prop = ParentDirItem->ATime; break;
    case kpidMTime:  if (ParentDirItem) prop = ParentDirItem->MTime; break;
  }
  prop.Detach(value);
  return S_OK;
}

STDMETHODIMP CArchiveUpdateCallback::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)
{
  *parentType = NParentType::kDir;
  *parent = (UInt32)(Int32)-1;
  return S_OK;
}

STDMETHODIMP CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps)
{
  *numProps = 0;
  if (StoreNtSecurity)
    *numProps = 1;
  return S_OK;
}

STDMETHODIMP CArchiveUpdateCallback::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)
{
  *name = NULL;
  *propID = kpidNtSecure;
  return S_OK;
}

STDMETHODIMP CArchiveUpdateCallback::GetRootRawProp(PROPID
    #ifdef _USE_SECURITY_CODE
    propID
    #endif
    , const void **data, UInt32 *dataSize, UInt32 *propType)
{
  *data = 0;
  *dataSize = 0;
  *propType = 0;
  if (!StoreNtSecurity)
    return S_OK;
  #ifdef _USE_SECURITY_CODE
  if (propID == kpidNtSecure)
  {
    if (StdInMode)
      return S_OK;

    if (ParentDirItem)
    {
      if (ParentDirItem->SecureIndex < 0)
        return S_OK;
      const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[ParentDirItem->SecureIndex];
      *data = buf;
      *dataSize = (UInt32)buf.Size();
      *propType = NPropDataType::kRaw;
      return S_OK;
    }

    if (GetRootProps)
      return GetRootProps->GetRootRawProp(propID, data, dataSize, propType);
  }
  #endif
  return S_OK;
}

//    #ifdef _USE_SECURITY_CODE
//    #endif

STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
{
  *data = 0;
  *dataSize = 0;
  *propType = 0;

  if (propID == kpidNtSecure ||
      propID == kpidNtReparse)
  {
    if (StdInMode)
      return S_OK;

    const CUpdatePair2 &up = (*UpdatePairs)[index];
    if (up.UseArcProps && up.ExistInArchive() && GetRawProps)
      return GetRawProps->GetRawProp(
          ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex,
          propID, data, dataSize, propType);

    {
      const CUpdatePair2 &up = (*UpdatePairs)[index];
      /*
      if (!up.NewData)
        return E_FAIL;
      */
      if (up.IsAnti)
        return S_OK;
      
      #ifndef UNDER_CE
      const CDirItem &di = DirItems->Items[up.DirIndex];
      #endif

      #ifdef _USE_SECURITY_CODE
      if (propID == kpidNtSecure)
      {
        if (!StoreNtSecurity)
          return S_OK;
        if (di.SecureIndex < 0)
          return S_OK;
        const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[di.SecureIndex];
        *data = buf;
        *dataSize = (UInt32)buf.Size();
        *propType = NPropDataType::kRaw;
      }
      else
      #endif
      {
        // propID == kpidNtReparse
        if (!StoreSymLinks)
          return S_OK;
        #ifndef UNDER_CE
        const CByteBuffer *buf = &di.ReparseData2;
        if (buf->Size() == 0)
          buf = &di.ReparseData;
        if (buf->Size() != 0)
        {
          *data = *buf;
          *dataSize = (UInt32)buf->Size();
          *propType = NPropDataType::kRaw;
        }
        #endif
      }
 
      return S_OK;
    }
  }

  return S_OK;
}

#ifndef UNDER_CE

static UString GetRelativePath(const UString &to, const UString &from)
{
  UStringVector partsTo, partsFrom;
  SplitPathToParts(to, partsTo);
  SplitPathToParts(from, partsFrom);

  unsigned i;
  for (i = 0;; i++)
  {
    if (i + 1 >= partsFrom.Size() ||
        i + 1 >= partsTo.Size())
      break;
    if (CompareFileNames(partsFrom[i], partsTo[i]) != 0)
      break;
  }

  if (i == 0)
  {
    #ifdef _WIN32
    if (NName::IsDrivePath(to) ||
        NName::IsDrivePath(from))
      return to;
    #endif
  }

  UString s;
  unsigned k;
  
  for (k = i + 1; k < partsFrom.Size(); k++)
    s += L".." WSTRING_PATH_SEPARATOR;
  
  for (k = i; k < partsTo.Size(); k++)
  {
    if (k != i)
      s += WCHAR_PATH_SEPARATOR;
    s += partsTo[k];
  }

  return s;
}

#endif

STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
  COM_TRY_BEGIN
  const CUpdatePair2 &up = (*UpdatePairs)[index];
  NCOM::CPropVariant prop;

  if (up.NewData)
  {
    /*
    if (propID == kpidIsHardLink)
    {
      prop = _isHardLink;
      prop.Detach(value);
      return S_OK;
    }
    */
    if (propID == kpidSymLink)
    {
      if (index == _hardIndex_From)
      {
        prop.Detach(value);
        return S_OK;
      }
      if (up.DirIndex >= 0)
      {
        #ifndef UNDER_CE
        const CDirItem &di = DirItems->Items[up.DirIndex];
        // if (di.IsDir())
        {
          CReparseAttr attr;
          if (attr.Parse(di.ReparseData, di.ReparseData.Size()))
          {
            UString simpleName = attr.GetPath();
            if (attr.IsRelative())
              prop = simpleName;
            else
            {
              const UString phyPath = DirItems->GetPhyPath(up.DirIndex);
              FString fullPath;
              if (NDir::MyGetFullPathName(us2fs(phyPath), fullPath))
              {
                prop = GetRelativePath(simpleName, fs2us(fullPath));
              }
            }
            prop.Detach(value);
            return S_OK;
          }
        }
        #endif
      }
    }
    else if (propID == kpidHardLink)
    {
      if (index == _hardIndex_From)
      {
        const CKeyKeyValPair &pair = _map[_hardIndex_To];
        const CUpdatePair2 &up2 = (*UpdatePairs)[pair.Value];
        prop = DirItems->GetLogPath(up2.DirIndex);
        prop.Detach(value);
        return S_OK;
      }
      if (up.DirIndex >= 0)
      {
        prop.Detach(value);
        return S_OK;
      }
    }
  }
  
  if (up.IsAnti
      && propID != kpidIsDir
      && propID != kpidPath
      && propID != kpidIsAltStream)
  {
    switch (propID)
    {
      case kpidSize:  prop = (UInt64)0; break;
      case kpidIsAnti:  prop = true; break;
    }
  }
  else if (propID == kpidPath && up.NewNameIndex >= 0)
    prop = (*NewNames)[up.NewNameIndex];
  else if (propID == kpidShortName && up.NewNameIndex >= 0 && up.IsMainRenameItem)
  {
    // we can generate new ShortName here;
  }
  else if ((up.UseArcProps
      || (KeepOriginalItemNames && (propID == kpidPath || propID == kpidIsAltStream)))
      && up.ExistInArchive() && Archive)
    return Archive->GetProperty(ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex, propID, value);
  else if (up.ExistOnDisk())
  {
    const CDirItem &di = DirItems->Items[up.DirIndex];
    switch (propID)
    {
      case kpidPath:  prop = DirItems->GetLogPath(up.DirIndex); break;
      case kpidIsDir:  prop = di.IsDir(); break;
      case kpidSize:  prop = di.Size; break;
      case kpidAttrib:  prop = di.Attrib; break;
      case kpidCTime:  prop = di.CTime; break;
      case kpidATime:  prop = di.ATime; break;
      case kpidMTime:  prop = di.MTime; break;
      case kpidIsAltStream:  prop = di.IsAltStream; break;
      #if defined(_WIN32) && !defined(UNDER_CE)
      // case kpidShortName:  prop = di.ShortName; break;
      #endif
    }
  }
  prop.Detach(value);
  return S_OK;
  COM_TRY_END
}

static NSynchronization::CCriticalSection CS;

STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
{
  COM_TRY_BEGIN
  *inStream = NULL;
  const CUpdatePair2 &up = (*UpdatePairs)[index];
  if (!up.NewData)
    return E_FAIL;
  
  RINOK(Callback->CheckBreak());
  RINOK(Callback->Finilize());

  bool isDir = IsDir(up);

  if (up.IsAnti)
  {
    UString name;
    if (up.ArcIndex >= 0)
      name = (*ArcItems)[up.ArcIndex].Name;
    else if (up.DirIndex >= 0)
      name = DirItems->GetLogPath(up.DirIndex);
    RINOK(Callback->GetStream(name, true));
    
    /* 9.33: fixed. Handlers expect real stream object for files, even for anti-file.
       so we return empty stream */

    if (!isDir)
    {
      CBufInStream *inStreamSpec = new CBufInStream();
      CMyComPtr<ISequentialInStream> inStreamLoc = inStreamSpec;
      inStreamSpec->Init(NULL, 0);
      *inStream = inStreamLoc.Detach();
    }
    return S_OK;
  }
  
  RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), false));
 
  if (isDir)
    return S_OK;

  if (StdInMode)
  {
    CStdInFileStream *inStreamSpec = new CStdInFileStream;
    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
    *inStream = inStreamLoc.Detach();
  }
  else
  {
    CInFileStream *inStreamSpec = new CInFileStream;
    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);

    inStreamSpec->SupportHardLinks = StoreHardLinks;

    const UString path = DirItems->GetPhyPath(up.DirIndex);

    #if defined(_WIN32) && !defined(UNDER_CE)
    if (DirItems->Items[up.DirIndex].AreReparseData())
    {
      if (!inStreamSpec->File.OpenReparse(us2fs(path)))
      {
        return Callback->OpenFileError(path, ::GetLastError());
      }
    }
    else
    #endif
    if (!inStreamSpec->OpenShared(us2fs(path), ShareForWrite))
    {
      return Callback->OpenFileError(path, ::GetLastError());
    }

    if (StoreHardLinks)
    {
      CStreamFileProps props;
      if (inStreamSpec->GetProps2(&props) == S_OK)
      {
        if (props.NumLinks > 1)
        {
          CKeyKeyValPair pair;
          pair.Key1 = props.VolID;
          pair.Key2 = props.FileID_Low;
          pair.Value = index;
          unsigned numItems = _map.Size();
          unsigned pairIndex = _map.AddToUniqueSorted2(pair);
          if (numItems == _map.Size())
          {
            // const CKeyKeyValPair &pair2 = _map.Pairs[pairIndex];
            _hardIndex_From = index;
            _hardIndex_To = pairIndex;
            // we could return NULL as stream, but it's better to return real stream
            // return S_OK;
          }
        }
      }
    }

    if (ProcessedItemsStatuses)
    {
      NSynchronization::CCriticalSectionLock lock(CS);
      ProcessedItemsStatuses[up.DirIndex] = 1;
    }
    *inStream = inStreamLoc.Detach();
  }
  
  return S_OK;
  COM_TRY_END
}

STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)
{
  COM_TRY_BEGIN
  return Callback->SetOperationResult(operationResult);
  COM_TRY_END
}

STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
{
  if (VolumesSizes.Size() == 0)
    return S_FALSE;
  if (index >= (UInt32)VolumesSizes.Size())
    index = VolumesSizes.Size() - 1;
  *size = VolumesSizes[index];
  return S_OK;
}

STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
{
  COM_TRY_BEGIN
  FChar temp[16];
  ConvertUInt32ToString(index + 1, temp);
  FString res = temp;
  while (res.Len() < 2)
    res.InsertAtFront(FTEXT('0'));
  FString fileName = VolName;
  fileName += L'.';
  fileName += res;
  fileName += VolExt;
  COutFileStream *streamSpec = new COutFileStream;
  CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
  if (!streamSpec->Create(fileName, false))
    return ::GetLastError();
  *volumeStream = streamLoc.Detach();
  return S_OK;
  COM_TRY_END
}

STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
{
  COM_TRY_BEGIN
  return Callback->CryptoGetTextPassword2(passwordIsDefined, password);
  COM_TRY_END
}

STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password)
{
  COM_TRY_BEGIN
  return Callback->CryptoGetTextPassword(password);
  COM_TRY_END
}
