//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 {
  class SimpleValueTypeSample : public akaxiso::simpletype {
  public:
    bool read_text(std::istringstream &istm, const akaxiso::global_attributes &gattrs) {
      value_ = istm.rdbuf()->str();
      return true;
    }
    void write_text(std::ostream &ostm, const akaxiso::global_attributes &gattrs) const {
      ostm << value_;
    }

    void copy_to(SimpleValueTypeSample &rhs) const { rhs.value_ = value_; }
    bool is_equal_to(const SimpleValueTypeSample &rhs) const { return value_ == rhs.value_; }
    
    void set_value(const std::string &rhs) { value_ = rhs; }

    std::string value_;
  };

  class SimpleContentSample : public akaxiso::simplecontent_impl<SimpleContentSample, SimpleValueTypeSample> {
  public:
    static void initialize_types() {
      static_typeinfo().set_typename("sample_simplecontent");
      define_attribute("attribute", &SimpleContentSample::attribute_);
    }
    std::string attribute_;
  };

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

  void initialize_() {
    SimpleContentSample::initialize();
    MyDoc::initialize();
  }

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


class SimpleContentTest : public CppUnit::TestFixture {
  CPPUNIT_TEST_SUITE(SimpleContentTest);
//CUPPA:suite=+
  CPPUNIT_TEST(test_equality0);
  CPPUNIT_TEST(test_equality1);
  CPPUNIT_TEST(test_copy);
  CPPUNIT_TEST(test_replicate);
  CPPUNIT_TEST(test_serialize);
  CPPUNIT_TEST(test_parse);
//    CPPUNIT_TEST_EXCEPTION(test_wrongSimuence0, akaxiso::parseexception);
//    CPPUNIT_TEST_EXCEPTION(test_wrongSimuence1, 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(SimpleContentSample *sim){
    sim->value_.set_value("Test String for a SimpleContent.");
    sim->attribute_ = "Attribute test";
  }

  static SimpleContentSample* createSample() {
    SimpleContentSample *sim = SimpleContentSample::create();
    setValues(sim);
    return sim;
  }

//CUPPA:decl=+
  void test_typeinfo() {
    SimpleContentSample *sim = createSample();
    std::string simname = sim->get_typeinfo().get_typename();
    delete sim;
    CPPUNIT_ASSERT_EQUAL(std::string("sample_simplecontent"), simname);
  }


  void test_equality0(){
    SimpleContentSample *sim = createSample();
    SimpleContentSample *sim1 = createSample();

    bool isimual = sim->is_equal_to(sim1);
    delete sim;
    delete sim1;

    CPPUNIT_ASSERT_MESSAGE("Equality test failed.", isimual);
  }

  void test_equality1(){
    SimpleContentSample *sim = createSample();
    SimpleContentSample *sim1 = createSample();

    sim->value_.set_value("Test");

    bool isimual = sim->is_equal_to(sim1);
    delete sim;
    delete sim1;

    CPPUNIT_ASSERT_MESSAGE("Equality test failed.", !isimual);
  }


  void test_copy() {
    SimpleContentSample *sim = createSample();
    SimpleContentSample *sim1 = SimpleContentSample::create();
    sim->copy_to(sim1);
    bool isimual = sim->is_equal_to(sim1);

    delete sim;
    delete sim1;

    CPPUNIT_ASSERT_MESSAGE("Simuence::CopyTo failed.", isimual);
  }

  void test_replicate(){
    SimpleContentSample *sim = createSample();
    SimpleContentSample *sim1 = sim->replicate();
    bool isimual = sim->is_equal_to(sim1);
    delete sim;
    delete sim1;
    
    CPPUNIT_ASSERT_MESSAGE("Replication of Simuence instance failed.", isimual);
  }

  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() << std::endl;
  }

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

    bool is_equal = doc_->get_root()->is_equal_to(doc1_->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);
  }

//    void test_wrongSimuence0() {
    
//      adom::string doc = 
//        "<?xml version=\"1.0\"?>"
//        "<MyDoc>"
//        "  <double>0.2</double>"
//        "  <long>2</long>" // Should be <float>
//        "  <float>3.0</float>"
//        "  <short>2</short>"
//        "  <string>Test</string>"
//        "</MyDoc>";


//      adom::XMLParser parser;
//      doc1_ = static_cast<MyDoc*>(parser.parse(doc.c_str()));
//    }


//    void test_wrongSimuence1() {
    
//      adom::string doc = 
//        "<?xml version=\"1.0\"?>"
//        "<MyDoc>"
//        "  <double>0.2</double>"
//        "  <float>3.0</float>"
//        "  <long>2</long>"
//        "  <short>2</short>"
//        // Lack of element.
//        //      "  <string>Test</string>"
//        "</MyDoc>";
//      adom::XMLParser parser;
//      doc1_ = static_cast<MyDoc*>(parser.parse(doc.c_str()));
//    }


//CUPPA:decl=-
};

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

CPPUNIT_TEST_SUITE_REGISTRATION(SimpleContentTest);
