#include "QFramework/TQSampleInitializer.h"
#include "QFramework/TQSample.h"
#include "TFile.h"
#include "QFramework/TQUtils.h"
#include "QFramework/TQIterator.h"
#include "definitions.h"
#include "QFramework/TQLibrary.h"
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <cstdlib>
ClassImp(TQSampleInitializer)
TQSampleInitializer::TQSampleInitializer() :
TQSampleVisitor("init")
{
  
}
TQSampleInitializer::TQSampleInitializer(const TString& dirname, int depth) :
TQSampleVisitor("init")
{
  this->readDirectory(dirname,depth);
}
TQSampleInitializer::~TQSampleInitializer(){
  
}
namespace {
  inline TString makeFullPath(const TString& prefix, const TString& path){
    TString tmppath = TQStringUtils::makeASCII(path);
    int hashpos = tmppath.First("#");
    if(hashpos >= 0 && hashpos < tmppath.Length()) tmppath.Remove(hashpos);
    TString basepath(TQStringUtils::makeASCII(prefix));
    TQStringUtils::ensureLeadingText(tmppath,basepath);
    return tmppath;
  }
}
int TQSampleInitializer::visitSample(TQSample * sample, TString& message) {
  int retCode = this->visitSampleInternal(sample, message);
  if (retCode == visitOK) {
    
    this->stamp(sample);
  }
  return retCode;
}
int TQSampleInitializer::visitSampleInternal(TQSample * sample, TString& message){
  
  if(sample->isSubSample()) return visitOK;
  if(sample->getTagBoolDefault("~isInitialized",false)) return visitSKIPPEDOK;
  
  TString sampleName = sample->GetName();
  sample->getTagString("name",sampleName);
  sample->getTagString(".xsp.sampleName",sampleName);
  TString samplePath = sample->getPath();
  
  
  TString filename = this->getTagStringDefault("filenamePrefix","") + sampleName + this->getTagStringDefault("filenameSuffix",".root");
  TString subdir = this->getTagStringDefault("subdirectory","./");
  
  TString path;
  TString fullpath;
  TString fpattern;
  if(sample->getTagString(".xsp.filepath",path)){
    
    
    fullpath = sample->replaceInText(path);
    fullpath = TQStringUtils::makeASCII(fullpath);
    if(!this->initializeSample(sample,fullpath,message)) {
      if (getExitOnFail()) exit(66); 
      return visitFAILED;
    }
    this->setSampleNormalization(sample);
    return visitOK;
  } else if(this->fPaths){
    
    
    DEBUGclass("trying to retrieve object paths for filename '%s' from subdir '%s'",filename.Data(),subdir.Data());
    
    
    TList* paths = new TList();
    paths->SetOwner(true);
    TQFolderIterator storageSystems(this->fPaths->getListOfFolders("?"),true); 
    while (storageSystems.hasNext()) {
      TQFolder* storageSys = storageSystems.readNext();
      storageSys->detachFromBase(); 
      DEBUG("scanning storage system '%s'",storageSys->GetName());
      TList* thesePaths = storageSys->getObjectPaths(filename,subdir,TObjString::Class());
      DEBUG("found %d paths matching '%s' in '%s'",thesePaths->GetEntries(),filename.Data(),subdir.Data());
      this->fPaths->addFolder(storageSys);
      TQStringIterator pathItr(thesePaths,false); 
      while (pathItr.hasNext()) {
        TObjString* p = pathItr.readNext();
        if (!p) continue;
        
        TString s = makeFullPath(storageSys->getTagStringDefault("basepath",""),p->GetName());
        DEBUGclass("found path %s",s.Data());
        p->SetString( s );
      }
      
      thesePaths->SetOwner(false); 
      DEBUG("adding %d paths",thesePaths->GetEntries());
      paths->AddAll(thesePaths); 
      delete thesePaths; 
    }
    DEBUGclass("trying to initialize sample '%s' from list of length %d",sample->getPath().Data(),paths->GetEntries());
    paths->SetOwner(true);
    if(!paths || (paths->GetEntries() == 0)){
      
      
      message = "no valid file path given for '"+filename+"'";
      #ifdef _DEBUG_
      this->fPaths->print("rdt");
      #endif
      if(paths) delete paths;
      paths = nullptr;
      return visitWARN;
    } 
    if(paths->GetEntries() == 1){
      DEBUGclass("found exactly one entry for file '%s' in '%s'",filename.Data(),subdir.Data());
      
      
      
      fullpath = paths->First()->GetName();
      delete paths;
      paths = nullptr;
      if(!this->initializeSample(sample,fullpath,message)) { 
        if (getExitOnFail()) exit(66); 
        return visitFAILED;
      }
      this->setSampleNormalization(sample,1.);
      return visitOK;
    }
    if(paths->GetEntries() > 0){
      
      
      
      DEBUGclass("found %d entries for file '%s' in '%s'",paths->GetEntries(),filename.Data(),subdir.Data());
      TQIterator itr(paths,true); 
      int nOK = 0;
      double neventstotal = 0;
      while(itr.hasNext()){
	
	      fullpath = itr.readNext()->GetName();
        TString tmppath(fullpath);
        DEBUGclass("adding %s",fullpath.Data());
        TQSample* subSample = new TQSample(TQFolder::makeValidIdentifier(TQFolder::getPathTail(tmppath)));
        if(!sample->addSubSample(subSample)){
          if(sample->getObject(subSample->GetName())){
            message = TString::Format("unable to add subsample '%s', an object of this name exists already", subSample->GetName());
          } else {
            message = TString::Format("unable to add subsample '%s'", subSample->GetName());
          }
          DEBUGclass("error: %s",message.Data());
          delete subSample;
          return visitFAILED;
        } 
        TString subMessage;
        if(this->initializeSample(subSample,fullpath,subMessage)){
          DEBUGclass("initialized %s: %s",fullpath.Data(),subMessage.Data());
          nOK++;
          neventstotal += subSample->getTagDoubleDefault(".init.sumOfWeights",0);
          subSample->setTagString(TString::Format(".%s.message",this->GetName()), TQStringUtils::compactify(subMessage));
        } 
      }
      TQSampleIterator sitr(sample->getListOfFolders("?",TQSample::Class()),true);
      while(sitr.hasNext()){
        TQSample* s = sitr.readNext();
        this->setSampleNormalization(s,s->getTagDoubleDefault(".init.sumOfWeights",0)/neventstotal);
      }
      sample->setTagDouble(".init.sumOfWeightsTotal",neventstotal);
      if(nOK == paths->GetEntries()){
        message = TString::Format("multisample n=%d: all OK",nOK);
        return visitOK;
      } else if(nOK == 0){
        message = TString::Format("multisample n=%d: all FAILED",paths->GetEntries());
        if (getExitOnFail()) exit(66);
        return visitFAILED;
      } else {
        message = TString::Format("multisample n=%d: %d succeeded, %d failed",paths->GetEntries(),nOK,(paths->GetEntries()-nOK));
        if (getExitOnFail()) exit(66); 
        return visitFAILED;
      }
    }
  } else if(this->getTagString("dCacheFilePattern",fpattern)){
    
    
    TList* l = TQUtils::lsdCache(sample->replaceInText(fpattern),TQLibrary::getLocalGroupDisk(), TQLibrary::getDQ2PathHead(), TQLibrary::getdCachePathHead(), TQLibrary::getDQ2cmd());
    if(l->GetEntries() == 0){
      message = "no such dataset";
      if (getExitOnFail()) exit(66); 
      return visitFAILED;
    } else if(l->GetEntries() == 1){
      TObjString* s = dynamic_cast<TObjString*>(l->First());
      fullpath = TQStringUtils::makeASCII(s->GetName());
      if(!this->initializeSample(sample,fullpath,message)) {
	if (getExitOnFail()) exit(66); 
	return visitFAILED;
      }
      return visitOK;
    } else {
      TQStringIterator itr(l,true);
      while(itr.hasNext()){
        TObjString* s = itr.readNext();
        fullpath = TQStringUtils::makeASCII(s->GetName());
        TQSample* subSample = sample->addSelfAsSubSample(fullpath);
        if(!this->initializeSample(subSample,fullpath,message)) {
	  if (getExitOnFail()) exit(66); 
	  return visitFAILED;
	}
      }
      return visitOK;
    }
  } else {
    message = "no known paths";
    if (getExitOnFail()) exit(66); 
    return visitFAILED;
  }
  
  return visitWARN;
}
bool TQSampleInitializer::getExitOnFail() {
  return this->getTagBoolDefault("exitOnFail",false);
}
void TQSampleInitializer::setExitOnFail(bool ex) {
  this->setTagBool("exitOnFail",ex);
}
 TQSampleInitializer.cxx:1  TQSampleInitializer.cxx:2  TQSampleInitializer.cxx:3  TQSampleInitializer.cxx:4  TQSampleInitializer.cxx:5  TQSampleInitializer.cxx:6  TQSampleInitializer.cxx:7  TQSampleInitializer.cxx:8  TQSampleInitializer.cxx:9  TQSampleInitializer.cxx:10  TQSampleInitializer.cxx:11  TQSampleInitializer.cxx:12  TQSampleInitializer.cxx:13  TQSampleInitializer.cxx:14  TQSampleInitializer.cxx:15  TQSampleInitializer.cxx:16  TQSampleInitializer.cxx:17  TQSampleInitializer.cxx:18  TQSampleInitializer.cxx:19  TQSampleInitializer.cxx:20  TQSampleInitializer.cxx:21  TQSampleInitializer.cxx:22  TQSampleInitializer.cxx:23  TQSampleInitializer.cxx:24  TQSampleInitializer.cxx:25  TQSampleInitializer.cxx:26  TQSampleInitializer.cxx:27  TQSampleInitializer.cxx:28  TQSampleInitializer.cxx:29  TQSampleInitializer.cxx:30  TQSampleInitializer.cxx:31  TQSampleInitializer.cxx:32  TQSampleInitializer.cxx:33  TQSampleInitializer.cxx:34  TQSampleInitializer.cxx:35  TQSampleInitializer.cxx:36  TQSampleInitializer.cxx:37  TQSampleInitializer.cxx:38  TQSampleInitializer.cxx:39  TQSampleInitializer.cxx:40  TQSampleInitializer.cxx:41  TQSampleInitializer.cxx:42  TQSampleInitializer.cxx:43  TQSampleInitializer.cxx:44  TQSampleInitializer.cxx:45  TQSampleInitializer.cxx:46  TQSampleInitializer.cxx:47  TQSampleInitializer.cxx:48  TQSampleInitializer.cxx:49  TQSampleInitializer.cxx:50  TQSampleInitializer.cxx:51  TQSampleInitializer.cxx:52  TQSampleInitializer.cxx:53  TQSampleInitializer.cxx:54  TQSampleInitializer.cxx:55  TQSampleInitializer.cxx:56  TQSampleInitializer.cxx:57  TQSampleInitializer.cxx:58  TQSampleInitializer.cxx:59  TQSampleInitializer.cxx:60  TQSampleInitializer.cxx:61  TQSampleInitializer.cxx:62  TQSampleInitializer.cxx:63  TQSampleInitializer.cxx:64  TQSampleInitializer.cxx:65  TQSampleInitializer.cxx:66  TQSampleInitializer.cxx:67  TQSampleInitializer.cxx:68  TQSampleInitializer.cxx:69  TQSampleInitializer.cxx:70  TQSampleInitializer.cxx:71  TQSampleInitializer.cxx:72  TQSampleInitializer.cxx:73  TQSampleInitializer.cxx:74  TQSampleInitializer.cxx:75  TQSampleInitializer.cxx:76  TQSampleInitializer.cxx:77  TQSampleInitializer.cxx:78  TQSampleInitializer.cxx:79  TQSampleInitializer.cxx:80  TQSampleInitializer.cxx:81  TQSampleInitializer.cxx:82  TQSampleInitializer.cxx:83  TQSampleInitializer.cxx:84  TQSampleInitializer.cxx:85  TQSampleInitializer.cxx:86  TQSampleInitializer.cxx:87  TQSampleInitializer.cxx:88  TQSampleInitializer.cxx:89  TQSampleInitializer.cxx:90  TQSampleInitializer.cxx:91  TQSampleInitializer.cxx:92  TQSampleInitializer.cxx:93  TQSampleInitializer.cxx:94  TQSampleInitializer.cxx:95  TQSampleInitializer.cxx:96  TQSampleInitializer.cxx:97  TQSampleInitializer.cxx:98  TQSampleInitializer.cxx:99  TQSampleInitializer.cxx:100  TQSampleInitializer.cxx:101  TQSampleInitializer.cxx:102  TQSampleInitializer.cxx:103  TQSampleInitializer.cxx:104  TQSampleInitializer.cxx:105  TQSampleInitializer.cxx:106  TQSampleInitializer.cxx:107  TQSampleInitializer.cxx:108  TQSampleInitializer.cxx:109  TQSampleInitializer.cxx:110  TQSampleInitializer.cxx:111  TQSampleInitializer.cxx:112  TQSampleInitializer.cxx:113  TQSampleInitializer.cxx:114  TQSampleInitializer.cxx:115  TQSampleInitializer.cxx:116  TQSampleInitializer.cxx:117  TQSampleInitializer.cxx:118  TQSampleInitializer.cxx:119  TQSampleInitializer.cxx:120  TQSampleInitializer.cxx:121  TQSampleInitializer.cxx:122  TQSampleInitializer.cxx:123  TQSampleInitializer.cxx:124  TQSampleInitializer.cxx:125  TQSampleInitializer.cxx:126  TQSampleInitializer.cxx:127  TQSampleInitializer.cxx:128  TQSampleInitializer.cxx:129  TQSampleInitializer.cxx:130  TQSampleInitializer.cxx:131  TQSampleInitializer.cxx:132  TQSampleInitializer.cxx:133  TQSampleInitializer.cxx:134  TQSampleInitializer.cxx:135  TQSampleInitializer.cxx:136  TQSampleInitializer.cxx:137  TQSampleInitializer.cxx:138  TQSampleInitializer.cxx:139  TQSampleInitializer.cxx:140  TQSampleInitializer.cxx:141  TQSampleInitializer.cxx:142  TQSampleInitializer.cxx:143  TQSampleInitializer.cxx:144  TQSampleInitializer.cxx:145  TQSampleInitializer.cxx:146  TQSampleInitializer.cxx:147  TQSampleInitializer.cxx:148  TQSampleInitializer.cxx:149  TQSampleInitializer.cxx:150  TQSampleInitializer.cxx:151  TQSampleInitializer.cxx:152  TQSampleInitializer.cxx:153  TQSampleInitializer.cxx:154  TQSampleInitializer.cxx:155  TQSampleInitializer.cxx:156  TQSampleInitializer.cxx:157  TQSampleInitializer.cxx:158  TQSampleInitializer.cxx:159  TQSampleInitializer.cxx:160  TQSampleInitializer.cxx:161  TQSampleInitializer.cxx:162  TQSampleInitializer.cxx:163  TQSampleInitializer.cxx:164  TQSampleInitializer.cxx:165  TQSampleInitializer.cxx:166  TQSampleInitializer.cxx:167  TQSampleInitializer.cxx:168  TQSampleInitializer.cxx:169  TQSampleInitializer.cxx:170  TQSampleInitializer.cxx:171  TQSampleInitializer.cxx:172  TQSampleInitializer.cxx:173  TQSampleInitializer.cxx:174  TQSampleInitializer.cxx:175  TQSampleInitializer.cxx:176  TQSampleInitializer.cxx:177  TQSampleInitializer.cxx:178  TQSampleInitializer.cxx:179  TQSampleInitializer.cxx:180  TQSampleInitializer.cxx:181  TQSampleInitializer.cxx:182  TQSampleInitializer.cxx:183  TQSampleInitializer.cxx:184  TQSampleInitializer.cxx:185  TQSampleInitializer.cxx:186  TQSampleInitializer.cxx:187  TQSampleInitializer.cxx:188  TQSampleInitializer.cxx:189  TQSampleInitializer.cxx:190  TQSampleInitializer.cxx:191  TQSampleInitializer.cxx:192  TQSampleInitializer.cxx:193  TQSampleInitializer.cxx:194  TQSampleInitializer.cxx:195  TQSampleInitializer.cxx:196  TQSampleInitializer.cxx:197  TQSampleInitializer.cxx:198  TQSampleInitializer.cxx:199  TQSampleInitializer.cxx:200  TQSampleInitializer.cxx:201  TQSampleInitializer.cxx:202  TQSampleInitializer.cxx:203  TQSampleInitializer.cxx:204  TQSampleInitializer.cxx:205  TQSampleInitializer.cxx:206  TQSampleInitializer.cxx:207  TQSampleInitializer.cxx:208  TQSampleInitializer.cxx:209  TQSampleInitializer.cxx:210  TQSampleInitializer.cxx:211  TQSampleInitializer.cxx:212  TQSampleInitializer.cxx:213  TQSampleInitializer.cxx:214  TQSampleInitializer.cxx:215  TQSampleInitializer.cxx:216  TQSampleInitializer.cxx:217  TQSampleInitializer.cxx:218  TQSampleInitializer.cxx:219  TQSampleInitializer.cxx:220  TQSampleInitializer.cxx:221  TQSampleInitializer.cxx:222  TQSampleInitializer.cxx:223  TQSampleInitializer.cxx:224  TQSampleInitializer.cxx:225  TQSampleInitializer.cxx:226  TQSampleInitializer.cxx:227  TQSampleInitializer.cxx:228  TQSampleInitializer.cxx:229  TQSampleInitializer.cxx:230  TQSampleInitializer.cxx:231  TQSampleInitializer.cxx:232  TQSampleInitializer.cxx:233  TQSampleInitializer.cxx:234  TQSampleInitializer.cxx:235  TQSampleInitializer.cxx:236  TQSampleInitializer.cxx:237  TQSampleInitializer.cxx:238  TQSampleInitializer.cxx:239  TQSampleInitializer.cxx:240  TQSampleInitializer.cxx:241  TQSampleInitializer.cxx:242  TQSampleInitializer.cxx:243  TQSampleInitializer.cxx:244  TQSampleInitializer.cxx:245  TQSampleInitializer.cxx:246  TQSampleInitializer.cxx:247  TQSampleInitializer.cxx:248  TQSampleInitializer.cxx:249  TQSampleInitializer.cxx:250  TQSampleInitializer.cxx:251  TQSampleInitializer.cxx:252  TQSampleInitializer.cxx:253  TQSampleInitializer.cxx:254  TQSampleInitializer.cxx:255  TQSampleInitializer.cxx:256  TQSampleInitializer.cxx:257  TQSampleInitializer.cxx:258  TQSampleInitializer.cxx:259  TQSampleInitializer.cxx:260  TQSampleInitializer.cxx:261  TQSampleInitializer.cxx:262  TQSampleInitializer.cxx:263  TQSampleInitializer.cxx:264  TQSampleInitializer.cxx:265  TQSampleInitializer.cxx:266  TQSampleInitializer.cxx:267