#include "DumpBadElectronics.h"

#include "MessageService/MsgService.h"
#include "MinosObjectMap/MomNavigator.h"
#include "JobControl/JobCommand.h"
#include "JobControl/JobCModuleRegistry.h"

#include "RawData/RawRecord.h"
#include "RawData/RawHeader.h"
#include "RawData/RawDaqHeader.h"
#include "RawData/RawDaqSnarlHeader.h"
#include "RawData/RawChannelId.h"
  
#include "RawData/RawDaqHeaderBlock.h"
#include "RawData/RawSnarlHeaderBlock.h"
#include "RawData/RawTpSinglesSummaryBlock.h"

//
// $Log $
//
 
ClassImp(DumpBadElectronics)
 
CVSID("$Id: DumpBadElectronics.cxx,v 1.1 2006/03/19 17:24:34 blake Exp $");
 
JOBMODULE(DumpBadElectronics,"DumpBadElectronics","DumpBadElectronics");
 
DumpBadElectronics::DumpBadElectronics() :
  fTime(0),
  fRecord(0),
  fCounter(0),
  fDQHeader(0),
  fDQHotColdElectronics(0),
  fBadElectronicsFile(0),
  fBadElectronicsTree(0)
{
  MSG("DataQuality",Msg::kInfo) << " *** DumpBadElectronics::DumpBadElectronics() *** " << endl;

  // Create the monitoring objects which extract the
  // monitoring information from the raw data blocks

  fDQHeader = new DQHeader();
  fDQHotColdElectronics = new DQHotColdElectronics();
}

DumpBadElectronics::~DumpBadElectronics()
{
  MSG("DataQuality",Msg::kInfo) << " *** DumpBadElectronics::~DumpBadElectronics() *** " << endl;

  delete fDQHeader;  
  delete fDQHotColdElectronics;

}
                                                            
void DumpBadElectronics::BeginJob()
{
  MSG("DataQuality",Msg::kInfo) << " *** DumpBadElectronics::BeginJob() *** " << endl;

}

JobCResult DumpBadElectronics::Ana(const MomNavigator* mom)
{
  MSG("DataQuality",Msg::kDebug) << " *** DumpBadElectronics::Ana(...) *** " << endl;

  JobCResult result(JobCResult::kPassed);

  TObject* momobject = 0;

  fRecord=0;

  // PROCESS RAW RECORDS
  // ===================
  // Iterate over raw records in mom and extract
  // monitoring information from raw data blocks
                   
  TIter momitr(mom->FragmentIter());
  while((momobject = momitr())){
    if(momobject->InheritsFrom("RawRecord")){
      fRecord=1;
      fCounter++;
      MSG("DataQuality",Msg::kInfo) << "  *** RAW RECORD [" << fCounter << "] ***  " << endl;
      RawRecord* rawrec = dynamic_cast<RawRecord*>(momobject);

      // Process the raw header
      this->ProcessHeader((TObject*)(rawrec->GetRawHeader()));

      // Iterate over the raw blocks in raw record
      TIter rawrecitr = rawrec->GetRawBlockIter();
      TObject* tob = 0;
      while((tob = rawrecitr())){
        MSG("DataQuality",Msg::kDebug) << " " << tob->GetName() << endl;
        this->ProcessBlock(tob);
      }
                                                       
    }
  }
                                              
  if( !fRecord ){
    MSG("DataQuality",Msg::kWarning) << "  *** FAILED TO FIND RAW RECORD ***  " << endl;
    return result.SetFailed();
  }

  // WRITE OUT RESULTS
  // =================

  if( fDQHotColdElectronics->GetTime()>fTime ){
    fTime=fDQHotColdElectronics->GetTime();
    this->WriteOutResults();
  }

  return result;
}

const Registry& DumpBadElectronics::DefaultConfig() const
{
  MSG("DataQuality",Msg::kInfo) << " *** DumpBadElectronics::DefaultConfig() *** " << endl;
 
  static Registry r;
  r.SetName("DumpBadElectronics.config.default");
  r.UnLockValues();
  
  r.LockValues();
                                                 
  return r;
}
                                                  
void DumpBadElectronics::Config(const Registry&)
{
  MSG("DataQuality",Msg::kInfo) << " *** DumpBadElectronics::Config() *** " << endl;

}

void DumpBadElectronics::HandleCommand(JobCommand* command)
{
  TString cmd = command->PopCmd();
  if(cmd=="Set"){
    TString opt = command->PopOpt();
 
  }
}
 
void DumpBadElectronics::EndJob()
{
  MSG("DataQuality",Msg::kInfo) << " *** DumpBadElectronics::EndJob() *** " << endl;
 
  if(fBadElectronicsFile){
    MSG("DataQuality",Msg::kInfo) << " *** saving info to file ... " << endl;
    TDirectory* tmpd = gDirectory;
    fBadElectronicsFile->cd();
    fBadElectronicsTree->Write();
    fBadElectronicsFile->Close();
    gDirectory = tmpd;
    MSG("DataQuality",Msg::kInfo) << "      ... info saved to file *** " << endl;
  }
}

void DumpBadElectronics::ProcessHeader(TObject* obj)
{
                                                                  
  // DAQ HEADER
  // ==========
  if(obj->InheritsFrom("RawDaqHeader")){
    MSG("DataQuality",Msg::kDebug) << " ... found RawDaqHeader " << endl;
    RawDaqHeader* hdr = (RawDaqHeader*)(obj);
    fDQHeader->Process(hdr);
  }
                                                         
  // SNARL HEADER
  // ============
  if(obj->InheritsFrom("RawDaqSnarlHeader")){
    MSG("DataQuality",Msg::kDebug) << " ... found RawDaqSnarlHeader " << endl;
    RawDaqSnarlHeader* hdr = (RawDaqSnarlHeader*)(obj);
    fDQHeader->Process(hdr);
  }
}

void DumpBadElectronics::ProcessBlock(TObject* obj)
{
             
  // HEADER BLOCKS
  // =============
  if(obj->InheritsFrom("RawDaqHeaderBlock")){
    MSG("DataQuality",Msg::kDebug) << " ... found RawDaqHeaderBlock " << endl;
    RawDaqHeaderBlock* rdb = (RawDaqHeaderBlock*)(obj);
    fDQHeader->Process(rdb); 
  }
                              
  if(obj->InheritsFrom("RawSnarlHeaderBlock")){
    MSG("DataQuality",Msg::kDebug) << " ... found RawSnarlHeaderBlock " << endl;
    RawSnarlHeaderBlock* rdb = (RawSnarlHeaderBlock*)(obj);
    fDQHeader->Process(rdb);
  }
                                                          
  // TP SINGLES SUMMARY BLOCK
  // ========================
  if(obj->InheritsFrom("RawTpSinglesSummaryBlock")){
    MSG("DataQuality",Msg::kDebug) << " ... found RawTpSinglesSummaryBlock " << endl;
    RawTpSinglesSummaryBlock* rdb = (RawTpSinglesSummaryBlock*)(obj);
    fDQHotColdElectronics->Process(rdb);
  }

}

void DumpBadElectronics::WriteOutResults()
{
  MSG("DataQuality",Msg::kVerbose) << " *** DumpBadElectronics::WriteOutResults() *** " << endl;

  Time=fDQHotColdElectronics->GetTime();
  Crates=fDQHotColdElectronics->GetNumberOfCrates();
  CratesInReadout=fDQHotColdElectronics->GetNumberOfCratesInReadout();

  for(Int_t k=0;k<2;k++){
    ColdChips[k]=fDQHotColdElectronics->GetColdChips(k+1);
    HotChips[k]=fDQHotColdElectronics->GetHotChips(k+1);
  }

  if(!fBadElectronicsFile){
    TString mystring("badchips.root");
    TDirectory* tmpd = gDirectory;
    fBadElectronicsFile = new TFile(mystring.Data(),"RECREATE");
    fBadElectronicsTree = new TTree("BadChips","BadChips");
    fBadElectronicsTree->SetAutoSave(300);
    fBadElectronicsTree->Branch("Time",&Time,"Time/I");
    fBadElectronicsTree->Branch("Crates",&Crates,"Crates/I");
    fBadElectronicsTree->Branch("CratesInReadout",&CratesInReadout,"CratesInReadout/I");
    fBadElectronicsTree->Branch("ColdChips",ColdChips,"ColdChips[2]/I");
    fBadElectronicsTree->Branch("HotChips",HotChips,"HotChips[2]/I");
    gDirectory = tmpd;
  }
 
  if(fBadElectronicsFile){
    TDirectory* tmpd = gDirectory;
    fBadElectronicsFile->cd();
    fBadElectronicsTree->Fill();
    gDirectory = tmpd;
  }

}
