#include "xerces_parser.h"
#include "xerces_handler.h"
#include <assert.h>


using namespace aka2;

#ifndef USE_XERCESC

xerces_parser::xerces_parser() {
  assert(!"Not configured to use Xerces-C++");
}


#else

#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/framework/StdInInputSource.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <akaxiso/xerces/istream_inputsource.h>


xerces_parser::xerces_parser() : gattrs_(0) {}

xerces_parser::~xerces_parser() { 
}


document xerces_parser::parse_stdin(){
  xercesc::StdInInputSource is;
  return parse(is, "(stdin)");
}



document xerces_parser::parse(const char *buff){

  char *membuf_id = "(document on memory)";
  xercesc::MemBufInputSource membuf_is( reinterpret_cast<const XMLByte*>(buff),
			   strlen(buff),
			   membuf_id,
			   false);
  return parse(membuf_is, "(membuf)");
  
}


document xerces_parser::parse(const std::string& document){

  char *membuf_id = "(document on memory)";
  xercesc::MemBufInputSource membuf_is( reinterpret_cast<const XMLByte*>(document.c_str()),
			   document.length(),
			   membuf_id,
			   false);
  return parse(membuf_is, "(std::string)");
  
}


document xerces_parser::parse(std::istream &istm){

  IStreamInputSource istmsrc(istm);
  return parse(istmsrc, "(std::istream)");
  
}


document xerces_parser::parse_file(const std::string& filename){
  XMLCh * xch_filename = xercesc::XMLString::transcode(filename.c_str());
  xercesc::LocalFileInputSource file_is(xch_filename);
  xercesc::XMLString::release(&xch_filename);
  return parse(file_is, filename);
}



document xerces_parser::parse(xercesc::InputSource &is, const std::string &source_name) {
  
  bool do_namespaces = true;
  bool do_namespace_prefixes = false;
  bool do_schema = false;
  bool full_checking = false;
  xercesc::SAX2XMLReader::ValSchemes valschemes = xercesc::SAX2XMLReader::Val_Auto;

  xerces_handler *handler = new xerces_handler();
  handler->set_source_name(source_name);
  if (gattrs_ != 0)
    handler->set_gattrs(*gattrs_);

  xercesc::SAX2XMLReader* parser = xercesc::XMLReaderFactory::createXMLReader();
  parser->setFeature(xercesc::XMLUni::fgSAX2CoreNameSpaces, do_namespaces);
  parser->setFeature(xercesc::XMLUni::fgSAX2CoreNameSpacePrefixes, do_namespace_prefixes);

  parser->setFeature(xercesc::XMLUni::fgXercesSchema, do_schema);
  parser->setFeature(xercesc::XMLUni::fgXercesSchemaFullChecking, full_checking);

  if (valschemes == xercesc::SAX2XMLReader::Val_Auto)  {
      parser->setFeature(xercesc::XMLUni::fgSAX2CoreValidation, true);
      parser->setFeature(xercesc::XMLUni::fgXercesDynamic, true);
  }
  if (valschemes == xercesc::SAX2XMLReader::Val_Never)  {
      parser->setFeature(xercesc::XMLUni::fgSAX2CoreValidation, false);
  }
  if (valschemes == xercesc::SAX2XMLReader::Val_Always)  {
      parser->setFeature(xercesc::XMLUni::fgSAX2CoreValidation, true);
      parser->setFeature(xercesc::XMLUni::fgXercesDynamic, false);
  }


  parser->setContentHandler(handler);
  parser->setErrorHandler(handler);
  
  try {
    parser->parse(is);
  }
  catch ( ... ) {
    delete handler;
    delete parser;
    throw;
  }

  document doc = handler->get_document();
  delete handler;
  delete parser;
  return doc;
}


void xerces_parser::set_gattrs(global_attributes &gattrs) {
  gattrs_ = &gattrs;
}


#endif
