// 7zExtract.cpp

#include "StdAfx.h"

#include "../../../Common/ComTry.h"

#include "../../Common/ProgressUtils.h"

#include "7zDecode.h"
// #include "7z1Decode.h"
#include "7zFolderOutStream.h"
#include "7zHandler.h"

namespace NArchive {
namespace N7z {

struct CExtractFolderInfo
{
  #ifdef _7Z_VOL
  int VolumeIndex;
  #endif
  CNum FileIndex;
  CNum FolderIndex;
  CBoolVector ExtractStatuses;
  UInt64 UnpackSize;
  CExtractFolderInfo(
    #ifdef _7Z_VOL
    int volumeIndex,
    #endif
    CNum fileIndex, CNum folderIndex):
    #ifdef _7Z_VOL
    VolumeIndex(volumeIndex),
    #endif
    FileIndex(fileIndex),
    FolderIndex(folderIndex),
    UnpackSize(0)
  {
    if (fileIndex != kNumNoIndex)
    {
      ExtractStatuses.ClearAndSetSize(1);
      ExtractStatuses[0] = true;
    }
  };
};

STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
    Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
{
  COM_TRY_BEGIN
  bool testMode = (testModeSpec != 0);
  CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
  UInt64 importantTotalUnpacked = 0;

  bool allFilesMode = (numItems == (UInt32)(Int32)-1);
  if (allFilesMode)
    numItems =
    #ifdef _7Z_VOL
    _refs.Size();
    #else
    _db.Files.Size();
    #endif

  if(numItems == 0)
    return S_OK;

  /*
  if(_volumes.Size() != 1)
    return E_FAIL;
  const CVolume &volume = _volumes.Front();
  const CDbEx &_db = volume.Database;
  IInStream *_inStream = volume.Stream;
  */
  
  CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
  for (UInt32 ii = 0; ii < numItems; ii++)
  {
    // UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
    UInt32 ref2Index = allFilesMode ? ii : indices[ii];
    // const CRef2 &ref2 = _refs[ref2Index];

    // for (UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
    {
      #ifdef _7Z_VOL
      // const CRef &ref = ref2.Refs[ri];
      const CRef &ref = _refs[ref2Index];

      int volumeIndex = ref.VolumeIndex;
      const CVolume &volume = _volumes[volumeIndex];
      const CDbEx &db = volume.Database;
      UInt32 fileIndex = ref.ItemIndex;
      #else
      const CDbEx &db = _db;
      UInt32 fileIndex = ref2Index;
      #endif

      CNum folderIndex = db.FileIndexToFolderIndexMap[fileIndex];
      if (folderIndex == kNumNoIndex)
      {
        extractFolderInfoVector.Add(CExtractFolderInfo(
            #ifdef _7Z_VOL
            volumeIndex,
            #endif
            fileIndex, kNumNoIndex));
        continue;
      }
      if (extractFolderInfoVector.IsEmpty() ||
        folderIndex != extractFolderInfoVector.Back().FolderIndex
        #ifdef _7Z_VOL
        || volumeIndex != extractFolderInfoVector.Back().VolumeIndex
        #endif
        )
      {
        extractFolderInfoVector.Add(CExtractFolderInfo(
            #ifdef _7Z_VOL
            volumeIndex,
            #endif
            kNumNoIndex, folderIndex));
        UInt64 unpackSize = db.GetFolderUnpackSize(folderIndex);
        importantTotalUnpacked += unpackSize;
        extractFolderInfoVector.Back().UnpackSize = unpackSize;
      }
      
      CExtractFolderInfo &efi = extractFolderInfoVector.Back();
      
      // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
      CNum startIndex = db.FolderStartFileIndex[folderIndex];
      for (CNum index = efi.ExtractStatuses.Size();
          index <= fileIndex - startIndex; index++)
      {
        // UInt64 unpackSize = _db.Files[startIndex + index].UnpackSize;
        // Count partial_folder_size
        // efi.UnpackSize += unpackSize;
        // importantTotalUnpacked += unpackSize;
        efi.ExtractStatuses.Add(index == fileIndex - startIndex);
      }
    }
  }

  RINOK(extractCallback->SetTotal(importantTotalUnpacked));

  CDecoder decoder(
    #ifdef _ST_MODE
    false
    #else
    true
    #endif
    );
  // CDecoder1 decoder;

  UInt64 totalPacked = 0;
  UInt64 totalUnpacked = 0;
  UInt64 curPacked, curUnpacked;

  CLocalProgress *lps = new CLocalProgress;
  CMyComPtr<ICompressProgressInfo> progress = lps;
  lps->Init(extractCallback, false);

  for (unsigned i = 0;; i++, totalUnpacked += curUnpacked, totalPacked += curPacked)
  {
    lps->OutSize = totalUnpacked;
    lps->InSize = totalPacked;
    RINOK(lps->SetCur());

    if (i >= extractFolderInfoVector.Size())
      break;
    
    const CExtractFolderInfo &efi = extractFolderInfoVector[i];
    curUnpacked = efi.UnpackSize;
    curPacked = 0;

    CFolderOutStream *folderOutStream = new CFolderOutStream;
    CMyComPtr<ISequentialOutStream> outStream(folderOutStream);

    #ifdef _7Z_VOL
    const CVolume &volume = _volumes[efi.VolumeIndex];
    const CDbEx &db = volume.Database;
    #else
    const CDbEx &db = _db;
    #endif

    CNum startIndex;
    if (efi.FileIndex != kNumNoIndex)
      startIndex = efi.FileIndex;
    else
      startIndex = db.FolderStartFileIndex[efi.FolderIndex];

    HRESULT result = folderOutStream->Init(&db,
        #ifdef _7Z_VOL
        volume.StartRef2Index,
        #else
        0,
        #endif
        startIndex,
        &efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0);

    RINOK(result);

    if (efi.FileIndex != kNumNoIndex)
      continue;

    CNum folderIndex = efi.FolderIndex;
    curPacked = _db.GetFolderFullPackSize(folderIndex);

    #ifndef _NO_CRYPTO
    CMyComPtr<ICryptoGetTextPassword> getTextPassword;
    if (extractCallback)
      extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
    #endif

    try
    {
      #ifndef _NO_CRYPTO
        bool isEncrypted = false;
        bool passwordIsDefined = false;
      #endif

      HRESULT result = decoder.Decode(
          EXTERNAL_CODECS_VARS
          #ifdef _7Z_VOL
            volume.Stream,
          #else
            _inStream,
          #endif
          db.ArcInfo.DataStartPosition,
          db, folderIndex,
          outStream,
          progress
          _7Z_DECODER_CRYPRO_VARS
          #if !defined(_7ZIP_ST) && !defined(_SFX)
            , true, _numThreads
          #endif
          );

      if (result == S_FALSE)
      {
        RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
        continue;
      }
      if (result == E_NOTIMPL)
      {
        RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kUnsupportedMethod));
        continue;
      }
      if (result != S_OK)
        return result;
      if (folderOutStream->WasWritingFinished() != S_OK)
      {
        RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
        continue;
      }
    }
    catch(...)
    {
      RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
      continue;
    }
  }
  return S_OK;
  COM_TRY_END
}

}}
