#include "hsrckeeper.h"
#include "hdiskspace.h"
#include "TSystem.h"
#include "TRegexp.h"
#include "TPRegexp.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ClassImp(HSrcKeeper)
HSrcKeeper::HSrcKeeper(const char* name,const char* title)
    : TNamed(name,title)
{
}
HSrcKeeper::~HSrcKeeper(void)
{
}
TMacro*  HSrcKeeper::newFile(TString fname)
{
    
    
    
    
    TString n = fname;
    TMacro* m = NULL;
    ifstream input;
    input.open(fname);
    if(input.fail()) return m;
    m = new TMacro();
    m ->SetName(n.Data());
    Char_t line[4000];
    while(!input.eof()){
	input.getline(line,4000);
	m->AddLine(line);
    }
    input.close();
    return  m;
}
Bool_t HSrcKeeper::addSourceFile(TString name)
{
    
    
    
    TMacro* m = newFile(name);
    if(m) {
	cout<<name.Data()<<endl;
	source.AddLast(m);
	return kTRUE;
    }
    else  Error("addSourceFiles()","could not create macro for %s !",name.Data());
    return kFALSE;
}
Int_t HSrcKeeper::addSourceFiles(TString dir,TString regexp)
{
    
    
    
    vector<TString> files;
    HFileSys::lsFiles(dir,files,kTRUE);
    sort(files.begin(),files.end());
    TPRegexp expr(regexp);
    Int_t n=0;
    for(UInt_t i=0;i<files.size();i++){
	TString name = files[i];
	if(name(expr) != "") {
	    cout<<name.Data()<<endl;
	    TMacro* m = newFile(name);
	    if(m) {source.AddLast(m);n++;}
	    else  Error("addSourceFiles()","could not create macro!");
	}
    }
    cout<<"added n "<<n<<" files"<<endl;
    return n;
}
Int_t HSrcKeeper::addSourceFilesRecursive(TString dir,TString regexp)
{
    
    
    vector<TString> files;
    HFileSys::lsFilesRecursive(dir,files);
    sort(files.begin(),files.end());
    TPRegexp expr(regexp);
    Int_t n=0;
    for(UInt_t i=0;i<files.size();i++){
	TString name = files[i];
	if(name(expr) != "") {
	    cout<<name.Data()<<endl;
	    TMacro* m = newFile(name);
	    if(m) {source.AddLast(m);n++;}
	    else  Error("addSourceFiles()","could not create macro!");
	}
    }
    cout<<"added n "<<n<<" files"<<endl;
    return n;
}
void HSrcKeeper::print(TString regexp,Bool_t show)
{
    
    
    TPRegexp expr(regexp);
    TString name;
    for(Int_t i=0;i<source.GetEntries();i++){
	TMacro* m = (TMacro*) source.At(i);
        name = m->GetName() ;
	if(name(expr)!= ""){
	    
	    if(show)  {
                cout<<"-------------------------------------------------------------"<<endl;
		cout<<m->GetName()<<endl;
		m->Print();
	    } else cout<<m->GetName()<<endl;
	}
    }
}
void HSrcKeeper::extract(TString destinationdir,TString replacedir, TString regexp)
{
    
    
    
    TPRegexp expr(regexp);
    if(destinationdir.EndsWith("/")) destinationdir.Replace(destinationdir.Length()-1,1,"");
    if(replacedir.EndsWith("/")    ) replacedir    .Replace(replacedir    .Length()-1,1,"");
    if(gSystem->AccessPathName(destinationdir.Data())!=0){
	if( gSystem->mkdir(destinationdir.Data()) ==-1) {
	    Error("extract()","Could not create destination dir %s. skipped.",destinationdir.Data());
            return;
	}
    }
    TString name;
    for(Int_t i=0;i<source.GetEntries();i++){
	TMacro* m = (TMacro*) source.At(i);
        name = m->GetName() ;
	if(name(expr)!= ""){
	    cout<<m->GetName()<<endl;
	    name.Replace(0,replacedir.Length(),"");
	    TString dir = gSystem->DirName(name.Data());
	    if(gSystem->AccessPathName(Form("%s/%s",destinationdir.Data(),dir.Data()))!=0)
	    {
		if( gSystem->mkdir(Form("%s/%s",destinationdir.Data(),dir.Data()),kTRUE) ==-1)
		{
		    Error("extract()","Could not create destination dir %s. skipped.",destinationdir.Data());
                    continue;
		}
	    }
	    m->SaveSource(Form("%s/%s",destinationdir.Data(),name.Data()));
	}
    }
}
TMacro* HSrcKeeper::getFile(TString fname,Bool_t usePath)
{
    
    
    if(fname == "") return 0;
    TString name;
    for(Int_t i=0;i<source.GetEntries();i++){
	TMacro* m = (TMacro*) source.At(i);
	name = m->GetName() ;
        if(!usePath) name = gSystem->BaseName(name.Data());
	if(name.CompareTo(fname.Data())==0) return m;
    }
    return 0;
}
Long64_t HSrcKeeper::Merge(TCollection *li){
    
    if (!li) return 0;
    return (Long64_t) 1;
}