// ExtractCallback.h

#ifndef __EXTRACT_CALLBACK_H
#define __EXTRACT_CALLBACK_H

#include "../../../../C/Alloc.h"

#include "../../../Common/MyCom.h"
#include "../../../Common/StringConvert.h"

#ifndef _SFX
#include "../Agent/IFolderArchive.h"
#endif

#include "../Common/ArchiveExtractCallback.h"
#include "../Common/ArchiveOpenCallback.h"

#ifndef _NO_CRYPTO
#include "../../IPassword.h"
#endif

#ifndef _SFX
#include "IFolder.h"
#endif

#include "ProgressDialog2.h"

#ifdef LANG
#include "LangUtils.h"
#endif

#ifndef _SFX

class CGrowBuf
{
  Byte *_items;
  size_t _size;

  CGrowBuf(const CGrowBuf &buffer);
  void operator=(const CGrowBuf &buffer);

public:
  bool ReAlloc_KeepData(size_t newSize, size_t keepSize)
  {
    void *buf = MyAlloc(newSize);
    if (!buf)
      return false;
    memcpy(buf, _items, keepSize);
    MyFree(_items);
    _items = (Byte *)buf;
    _size = newSize;
    return true;
  }

  CGrowBuf(): _items(0), _size(0) {}
  ~CGrowBuf() { MyFree(_items); }

  operator Byte *() { return _items; };
  operator const Byte *() const { return _items; };
  size_t Size() const { return _size; }
};

struct CVirtFile
{
  CGrowBuf Data;
  
  UInt64 Size; // real size
  UInt64 ExpectedSize; // the size from props request. 0 if unknown

  UString Name;

  bool CTimeDefined;
  bool ATimeDefined;
  bool MTimeDefined;
  bool AttribDefined;
  
  bool IsDir;
  bool IsAltStream;
  
  DWORD Attrib;

  FILETIME CTime;
  FILETIME ATime;
  FILETIME MTime;

  CVirtFile():
    CTimeDefined(false),
    ATimeDefined(false),
    MTimeDefined(false),
    AttribDefined(false),
    IsDir(false),
    IsAltStream(false) {}
};

class CVirtFileSystem:
  public ISequentialOutStream,
  public CMyUnknownImp
{
  UInt64 _totalAllocSize;

  size_t _pos;
  unsigned _numFlushed;
  bool _fileIsOpen;
  bool _fileMode;
  COutFileStream *_outFileStreamSpec;
  CMyComPtr<ISequentialOutStream> _outFileStream;
public:
  CObjectVector<CVirtFile> Files;
  UInt64 MaxTotalAllocSize;
  FString DirPrefix;
 
  CVirtFile &AddNewFile()
  {
    if (!Files.IsEmpty())
    {
      MaxTotalAllocSize -= Files.Back().Data.Size();
    }
    return Files.AddNew();
  }
  HRESULT CloseMemFile()
  {
    if (_fileMode)
    {
      return FlushToDisk(true);
    }
    CVirtFile &file = Files.Back();
    if (file.Data.Size() != file.Size)
    {
      file.Data.ReAlloc_KeepData((size_t)file.Size, (size_t)file.Size);
    }
    return S_OK;
  }

  bool IsStreamInMem() const
  {
    if (_fileMode)
      return false;
    if (Files.Size() < 1 || Files[0].IsAltStream || Files[0].IsDir)
      return false;
    return true;
  }
  size_t GetMemStreamWrittenSize() const { return _pos; }

  CVirtFileSystem(): _outFileStreamSpec(NULL), MaxTotalAllocSize((UInt64)0 - 1) {}

  void Init()
  {
    _totalAllocSize = 0;
    _fileMode = false;
    _pos = 0;
    _numFlushed = 0;
    _fileIsOpen = false;
  }

  HRESULT CloseFile(const FString &path);
  HRESULT FlushToDisk(bool closeLast);
  size_t GetPos() const { return _pos; }

  MY_UNKNOWN_IMP
  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};

#endif
  
class CExtractCallbackImp:
  public IExtractCallbackUI, // it includes IFolderArchiveExtractCallback
  public IOpenCallbackUI,
  #ifndef _SFX
  public IFolderOperationsExtractCallback,
  public IFolderExtractToStreamCallback,
  public ICompressProgressInfo,
  #endif
  #ifndef _NO_CRYPTO
  public ICryptoGetTextPassword,
  #endif
  public CMyUnknownImp
{
  HRESULT MessageError(const char *message, const FString &path);
public:
  MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback)
  #ifndef _SFX
  MY_QUERYINTERFACE_ENTRY(IFolderOperationsExtractCallback)
  MY_QUERYINTERFACE_ENTRY(IFolderExtractToStreamCallback)
  MY_QUERYINTERFACE_ENTRY(ICompressProgressInfo)
  #endif
  #ifndef _NO_CRYPTO
  MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword)
  #endif
  MY_QUERYINTERFACE_END
  MY_ADDREF_RELEASE

  INTERFACE_IProgress(;)
  INTERFACE_IOpenCallbackUI(;)

  // IFolderArchiveExtractCallback
  // STDMETHOD(SetTotalFiles)(UInt64 total);
  // STDMETHOD(SetCompletedFiles)(const UInt64 *value);
  STDMETHOD(AskOverwrite)(
      const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
      const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
      Int32 *answer);
  STDMETHOD (PrepareOperation)(const wchar_t *name, bool isFolder, Int32 askExtractMode, const UInt64 *position);

  STDMETHOD(MessageError)(const wchar_t *message);
  STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted);

  // IExtractCallbackUI
  
  HRESULT BeforeOpen(const wchar_t *name);
  HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted);
  HRESULT SetError(int level, const wchar_t *name,
      UInt32 errorFlags, const wchar_t *errors,
      UInt32 warningFlags, const wchar_t *warnings);
  HRESULT ThereAreNoFiles();
  HRESULT ExtractResult(HRESULT result);
  HRESULT OpenTypeWarning(const wchar_t *name, const wchar_t *okType, const wchar_t *errorType);

  #ifndef _NO_CRYPTO
  HRESULT SetPassword(const UString &password);
  #endif

  #ifndef _SFX
  // IFolderOperationsExtractCallback
  STDMETHOD(AskWrite)(
      const wchar_t *srcPath,
      Int32 srcIsFolder,
      const FILETIME *srcTime,
      const UInt64 *srcSize,
      const wchar_t *destPathRequest,
      BSTR *destPathResult,
      Int32 *writeAnswer);
  STDMETHOD(ShowMessage)(const wchar_t *message);
  STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath);
  STDMETHOD(SetNumFiles)(UInt64 numFiles);
  INTERFACE_IFolderExtractToStreamCallback(;)
  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
  #endif

  // ICryptoGetTextPassword
  #ifndef _NO_CRYPTO
  STDMETHOD(CryptoGetTextPassword)(BSTR *password);
  #endif

private:
  UString _currentArchivePath;
  bool _needWriteArchivePath;

  UString _currentFilePath;
  bool _isFolder;

  bool _isAltStream;
  UInt64 _curSize;
  bool _curSizeDefined;
  UString _filePath;
  // bool _extractMode;
  // bool _testMode;
  bool _newVirtFileWasAdded;
  bool _needUpdateStat;


  HRESULT SetCurrentFilePath2(const wchar_t *filePath);
  void AddError_Message(LPCWSTR message);

  #ifndef _SFX
  bool _hashStreamWasUsed;
  COutStreamWithHash *_hashStreamSpec;
  CMyComPtr<ISequentialOutStream> _hashStream;
  IHashCalc *_hashCalc; // it's for stat in Test operation
  #endif

public:

  #ifndef _SFX
  CVirtFileSystem *VirtFileSystemSpec;
  CMyComPtr<ISequentialOutStream> VirtFileSystem;
  #endif

  bool ProcessAltStreams;

  bool StreamMode;

  CProgressDialog *ProgressDialog;
  #ifndef _SFX
  UInt64 NumFolders;
  UInt64 NumFiles;
  bool NeedAddFile;
  #endif
  UInt32 NumArchiveErrors;
  bool ThereAreMessageErrors;
  NExtract::NOverwriteMode::EEnum OverwriteMode;

  #ifndef _NO_CRYPTO
  bool PasswordIsDefined;
  bool PasswordWasAsked;
  UString Password;
  #endif

  CExtractCallbackImp():
    #ifndef _NO_CRYPTO
    PasswordIsDefined(false),
    PasswordWasAsked(false),
    #endif
    OverwriteMode(NExtract::NOverwriteMode::kAsk),
    StreamMode(false),
    ProcessAltStreams(true)
    #ifndef _SFX
    , _hashCalc(NULL)
    #endif
    {}
   
  ~CExtractCallbackImp();
  void Init();

  #ifndef _SFX
  void SetHashCalc(IHashCalc *hashCalc) { _hashCalc = hashCalc; }

  void SetHashMethods(IHashCalc *hash)
  {
    if (!hash)
      return;
    _hashStreamSpec = new COutStreamWithHash;
    _hashStream = _hashStreamSpec;
    _hashStreamSpec->_hash = hash;
  }
  #endif

  bool IsOK() const { return NumArchiveErrors == 0 && !ThereAreMessageErrors; }
};

#endif
