//CUPPA:include=+
//CUPPA:include=-
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestAssert.h>

#include <xercesc/util/PlatformUtils.hpp>

#include <akaxiso/akaxiso.h>
#include <akaxiso/xerces/parser.h>

//CUPPA:namespace=+
//CUPPA:namespace=-


namespace {

  struct test { 
    const char *prefix() const { return "test"; }
    const char *uri() const { return "test_uri"; }
  };

  class SeqSample : public akaxiso::sequence_impl<SeqSample> {
  public:

    static void initialize_types() {
      static_typeinfo().set_typename("test:sample_sequence");
      define_member("double", &SeqSample::dbl_);
      define_member("float", &SeqSample::float_);
      define_member("long", &SeqSample::long_);
      define_member("short", &SeqSample::short_);
      define_member("string", &SeqSample::string_);
    }    

    double dbl_;
    float float_;
    long long_;
    short short_;
    std::string string_;
  };

  class MyDoc : public akaxiso::document_impl<MyDoc, SeqSample> {
  public:
    static void initialize_types() {
      define_document("test:MyDoc");
    }
  };

  void initialize_() {
    akaxiso::initialize_namespace<test>();
    SeqSample::initialize();
    MyDoc::initialize();
  }

  void uninitialize_() {
    SeqSample::uninitialize();
    MyDoc::uninitialize();
  }
}


class NamespaceTest : public CppUnit::TestFixture {
  CPPUNIT_TEST_SUITE(NamespaceTest);
//CUPPA:suite=+
  CPPUNIT_TEST(test_serialize);
  CPPUNIT_TEST(test_parse);
//    CPPUNIT_TEST_EXCEPTION(test_wrongSequence0, akaxiso::parseexception);
//    CPPUNIT_TEST_EXCEPTION(test_wrongSequence1, akaxiso::parseexception);
//CUPPA:suite=-
  CPPUNIT_TEST_SUITE_END();
private:

//    // your stuff...
  MyDoc *doc_;
  MyDoc *doc1_;

public:

  virtual void setUp() { 
//     XMLPlatformUtils::Initialize();
    akaxiso::initialize();
    initialize_();
    doc_ = NULL;
    doc1_ = NULL;
  }

  virtual void tearDown(){
    if (doc_)
      delete doc_;
    if (doc1_)
      delete doc1_;
   
    uninitialize_();
    akaxiso::uninitialize();
//     XMLPlatformUtils::Terminate();
  }


  static void setValues(SeqSample *seq){
    seq->dbl_ = 0.2253432222;
    seq->float_ = 0.225f;
    seq->long_ = 1638453;
    seq->short_ = 32600;
    seq->string_ = "Test String for a member in Sequence.";
  }

  static SeqSample* createSample() {
    SeqSample *seq = SeqSample::create();
    setValues(seq);
    return seq;
  }

//CUPPA:decl=+
  void test_serialize() {
    std::ostringstream ostm;
    akaxiso::xmlserializer ser;
    
    doc_ = MyDoc::create();
    setValues(doc_->get_root());
    ser.serialize(doc_, ostm);

//    std::cout << ostm.rdbuf()->str();
  }

  void test_parse() {
    std::ostringstream ostm;
    akaxiso::xmlserializer ser;
    
    doc_ = MyDoc::create();
    setValues(doc_->get_root());
    ser.serialize(doc_, ostm);
    
    akaxiso::yggxml_parser parser;
    doc_ = static_cast<MyDoc*>(parser.parse(ostm.rdbuf()->str()));

    bool is_equal = doc_->get_root()->is_equal_to(doc_->get_root());
    if (!is_equal) {
      ser.serialize(doc_, ostm);
      std::cout << ostm.str();
    }

    CPPUNIT_ASSERT_MESSAGE("Parsed document is not the same as original.", is_equal);
  }

//CUPPA:decl=-
};

//CUPPA:impl=+
//CUPPA:impl=-

CPPUNIT_TEST_SUITE_REGISTRATION(NamespaceTest);
