#include <string>
#include <iostream>
#include <iomanip>
#include <set>
#include <algorithm>

#include "JDB/JDB.hh"
#include "JDB/JSelector.hh"
#include "JDB/JSelectorSupportkit.hh"
#include "JDB/JDBToolkit.hh"
#include "JDB/JDetectors.hh"
#include "JDB/JSonSupportkit.hh"

#include "JSon/JSon.hh"
#include "JSon/JSupport.hh"

#include "JLang/JPredicate.hh"

#include "Jeep/JPrint.hh"
#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"


/**
 * \file
 *
 * Auxiliary program to extract detectors from database.
 * \author mdejong
 */
int main(int argc, char **argv)
{
  using namespace std;
  using namespace JPP;

  JServer     server;
  string      usr;
  string      pwd;
  string      cookie;
  set<string> filter;
  int         debug;
  
  try {

    JParser<> zap("Auxiliary program to extract detectors from database.");
    
    zap['s'] = make_field(server)     = getServernames();
    zap['u'] = make_field(usr)        = "";
    zap['!'] = make_field(pwd)        = "";
    zap['C'] = make_field(cookie)     = "";
    zap['F'] = make_field(filter)     = JPARSER::initialised();
    zap['d'] = make_field(debug)      = 2;
    
    zap(argc, argv);
  }
  catch(const exception &error) {
    FATAL(error.what() << endl);
  }


  try {

    JDB::reset(usr, pwd, cookie);

    typedef vector<JDetectors>        detector_typeA;
    typedef vector<APIV2::JDetector>  detector_typeB;

    detector_typeA detectorA;
    detector_typeB detectorB;

    {
      ResultSet& rs  = getResultSet(JDetectors::getName());

      for (JDetectors object; rs >> object; ) {
	detectorA.push_back(object);
      }

      rs.Close();
    }
    {
      json js;

      to_json(js, APIV2::JDetector::getName());

      detectorB = js[Data_t].get<detector_typeB>();
    }

    for (const auto& detector : detectorA) {
      if (filter.count(detector.OID) == 0) {
	ASSERT(find_if(detectorB.begin(), detectorB.end(), make_predicate(&APIV2::JDetector::DetOID, detector.OID)) != detectorB.end(), 
	       detector.OID);
      }
    }

    for (const auto& detector : detectorB) {
      if (filter.count(detector.DetOID) == 0) {
	ASSERT(find_if(detectorA.begin(), detectorA.end(), make_predicate(&JDetectors::OID, detector.DetOID)) != detectorA.end(), 
	       detector.DetOID);
      }
    }
  }
  catch(const exception& error) {
    FATAL(error.what() << endl);
  }

  return 0;
}