/*
*  Naamari - an AES/SHA-based manual file crypto-synchronizer for cloud transfers
*  Copyright (c) 2015-2017 Sunkware
*  Key FP = 6B6D C8E9 3438 6E9C 3D97  56E5 2CE9 A476 99EF 28F6
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*  See the GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*  ----------------------------------------------------------------
*  WWW:       sunkware.org
*  E-mail:    sunkware@gmail.com
*  ----------------------------------------------------------------
*/

#include "sizer.h"

namespace cryptrav
{


Sizer::Sizer(ContextGlob* pContext, StateGlob* pState)
{
 contextP = pContext;
 stateP = pState;
}


qint64         Sizer::size(QString pathInNominis, QString objName, SizeType sizeType)
{
 Pather        pather(contextP);

 Translator    translator(contextP, stateP);


 QFile         nomen(pather.getNominisAbs(pathInNominis) + objName);

 if ( !nomen.exists() )
  return CTERR_OBJECT_NOT_FOUND;

 QFileInfo     nomenInfo(nomen);

 qint64        result = 0;


 if ( nomenInfo.isDir() ) // Dir. Additional checks and recursion for list of its elements follow...
  {
   QFileInfoList entryInfoList = QDir(pather.getNominisAbs(pathInNominis) + objName).entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::DirsFirst);

   for (int i = 0; i < entryInfoList.count(); i++)
    {
     Sizer sizer(contextP, stateP);

     result += sizer.size(pathInNominis + objName + "/", (entryInfoList.at(i)).fileName(), sizeType);
    }

  }

   else // File. Checking times and states...

  {
   OMEN::NomenData nomenData;
   OMEN::clearNomenData(&nomenData);


   if ( OMEN::readNomen(nomenInfo.absoluteFilePath(), &nomenData) == CTERR_OK )
    {
     QString cryptomenStr = translator.makeCryptomenStr(nomenData.randomen);


     OMEN::CryptomenData cryptomenData;
     OMEN::clearCryptomenData(&cryptomenData);


     if ( OMEN::readCryptomen(pather.getHarbourAbs("/." + cryptomenStr), &cryptomenData) == CTERR_OK )
      {

       if ( (sizeType == SizeNear) || (sizeType == SizePush) )
        {
         if (cryptomenData.isNear)
          {
           translator.decryptTwoQwords( cryptomenData.nearSalt, &(cryptomenData.nearTime), &(cryptomenData.nearSize) );

           if ( (sizeType == SizeNear) || ( (sizeType == SizePush) && (cryptomenData.action == ACTION_PUSH)) ) {
             result = cryptomenData.nearSize;
            }

          }

        }
         else  // sizeType is Far/Pull/Erase
        {
         if (cryptomenData.isFar)
          {
           translator.decryptTwoQwords( cryptomenData.farSalt, &(cryptomenData.farTime), &(cryptomenData.farSize) );

           if ( (sizeType == SizeFar) || ((sizeType == SizePull) && (cryptomenData.action == ACTION_PULL)) || ((sizeType == SizeErase) && (cryptomenData.action == ACTION_UNCLOUD)) ) {
             result = cryptomenData.farSize;
            }

          }

        }

      }

     OMEN::clearCryptomenData(&cryptomenData);

     cryptomenStr.clear();
    }

   OMEN::clearNomenData(&nomenData);
  }


 return result;
}



Sizer::~Sizer()
{
 contextP = NULL;
 stateP = NULL;
}


} // namespace "cryptrav"
