#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>

#include "TFile.h"
#include "TH1D.h"
#include "TMath.h"
#include "TROOT.h"

#include "TApplication.h"
#include "TLegend.h"
#include "TGraphErrors.h"

#include "km3net-dataformat/online/JDAQ.hh"
#include "JDetector/JDetector.hh"
#include "JDetector/JDetectorToolkit.hh"
#include "JDetector/JModuleRouter.hh"
#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"
#include "JLang/JString.hh"
#include "JSupport/JMultipleFileScanner.hh"
#include "JSupport/JSupport.hh"


namespace {
 
  using namespace JPP;  
  using namespace std;

  double getCount (TH1D* hptr, int muon_threshold) {
    double count = 0;
    for (int i = hptr->GetXaxis()->FindBin(muon_threshold); i <= hptr->GetNbinsX(); i++) {
      count += hptr->GetBinContent(i);
    }
    return count;
  }

  double getLiveTime (TH1D* hptr, const JModule& module) {
    string label = getLabel(module);
    double livetime = hptr->GetBinContent(hptr->GetXaxis()->FindBin(label.c_str()));
    return livetime;
  }

}

/**
 * \file
 *
 * Auxiliary program to find depth dependence of multiplicity rates
 * \author mlincetto
 */
int main(int argc, char **argv)
{
  using namespace std;
  using namespace JPP;  
  
  //-----------------------------------------------------------
  // parameter interface
  //-----------------------------------------------------------
  

  string             inputFile;
  string             outputFile;
  string             detectorFile;
  int                line;
  int                debug;
  int                minMultiplicity;
  int                minLiveTime_s;
  // string             summaryFile;

  try { 

    JParser<> zap("Auxiliary program to find depth dependence of multiplicity rates");
    
    zap['f'] = make_field(inputFile, "JMM input file");
    zap['o'] = make_field(outputFile, "output file")          = "depthdependence.root";
    // zap['s'] = make_field(summaryFile, "summary file")        = "depthdependence.txt";
    zap['a'] = make_field(detectorFile);
    zap['d'] = make_field(debug)                = 1;
    zap['l'] = make_field(line)                 = 1;
    zap['M'] = make_field(minMultiplicity, "Minimum multiplicity") = 8;
    zap['T'] = make_field(minLiveTime_s, "Minimum DOM livetime [s] to be eligible for plotting") = 3600;

    zap(argc, argv);
  }
  
  catch(const exception &error) {
    FATAL(error.what() << endl);
  }


  //----------------------
  // loading detector file
  //----------------------
  
  JDetector detector;

  try {
    load(detectorFile, detector);
  }
  catch(const JException& error) {
    FATAL(error);
  }

  if (detector.empty())
    FATAL("Empty detector." << endl);

  const JModuleRouter router(detector);

  double utm_z = detector.getUTMZ();

  NOTICE("Detector base UTM z [m]: " << utm_z << endl);

  //-----------------------------------------------------------
  // load input files
  //-----------------------------------------------------------

    
  DEBUG("Loading input file " << inputFile << endl);

  TFile* in = TFile::Open(inputFile.c_str(), "exist");

  if (in == NULL || !in->IsOpen()) {
    FATAL("File: " << inputFile << " not opened." << endl);
  }

  //-----------------------------------------------------------
  // recover rates from histograms
  //-----------------------------------------------------------


  DEBUG("Loading livetime histogram from " << inputFile << endl);

  TH1D* liveTime = (TH1D*)in->Get("LiveTime");
    
  if (liveTime == NULL) {
    FATAL("Missing live time histogram.");
  }

  vector<double> depth;
  vector<double> rate_val;
  vector<double> rate_err;

  for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
    
    if (module->getString() != line) { continue; }

    STATUS("Loading data histogram for from input file: " << getLabel(*module) << "\t ID = " << module->getID()  << endl);

    TH1D* data_histogram = (TH1D*)in->Get(TString(getLabel(*module)) + "_P");

    if (data_histogram != NULL) {

      double data_count    = getCount(data_histogram, minMultiplicity);
      double data_livetime = getLiveTime(liveTime, *module);

      double module_depth = - utm_z - module->getZ();

      if (data_livetime > minLiveTime_s) {
	
	double val = data_count       / data_livetime;
	double err = sqrt(data_count) / data_livetime;

	NOTICE(module_depth << " " << val << endl);

	rate_val.push_back(val);
	rate_err.push_back(err);
	depth.push_back( module_depth);
    
      }

    }

  }


  TGraph* gr_data = new TGraphErrors(depth.size(), &depth[0], &rate_val[0], 0, &rate_err[0]);

  gr_data->SetTitle(TString("KM3NeT Preliminary; Depth [m]; Inclusive ") + Form("%d", minMultiplicity) + TString("-fold coincidence rate [Hz]"));

  TFile out(outputFile.c_str(), "recreate");

  gr_data->Write();

  out.Close();

  return 0;

}