#ifndef UIMA_XMISHAREDDATA_HPP
#define UIMA_XMISHAREDDATA_HPP
/** \file xmlwriter.hpp .
-----------------------------------------------------------------------------




 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.

-----------------------------------------------------------------------------

   Description:

-----------------------------------------------------------------------------

   \brief Used to output the CAS in XCAS format

-------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------- */
/*       Include dependencies                                              */
/* ----------------------------------------------------------------------- */
#include "uima/pragmas.hpp"

#include <iostream>
#include <vector>
#include <set>
#include <sstream>
#include <map>

#include "uima/msg.h"
#include "uima/exceptions.hpp"
/* ----------------------------------------------------------------------- */
/*       Constants                                                         */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Forward declarations                                              */
/* ----------------------------------------------------------------------- */


/* ----------------------------------------------------------------------- */
/*       Types / Classes                                                   */
/* ----------------------------------------------------------------------- */
namespace uima {

class XmlElementName {
  public:
	  std::string nsUri;
	  std::string shortName;
	  std::string qualifiedName;
	  XmlElementName(std::string ns, std::string sname, std::string qname) :
    nsUri(ns), shortName(sname), qualifiedName(qname) {}
  };

/**
 * Data structure representing an XML attribute.
 */
class XmlAttribute {
public:
 std::string name;
  std::string value;
  
  XmlAttribute(icu::UnicodeString name, icu::UnicodeString value) {
    this->name = ((UnicodeStringRef)name).asUTF8();
    this->value = ((UnicodeStringRef)value).asUTF8();
  }
  XmlAttribute(std::string name, std::string value) {
    this->name = name;
    this->value = value;
  }
};

 /**
   * Data structure holding all information about an XMI element
   * containing an out-of-typesystem FS.
   */
  class OotsElementData {
  public:
    /**
     * xmi:id of the element
     */
    int xmiId;

    /**
     * Name of the element, including XML namespace.
     */
    XmlElementName * elementName;

    /**
     * List of XmlAttribute objects each holding name and value of an attribute.
     */
    std::vector<XmlAttribute*>  attributes;
    
    /**
     * Map qualified name of an attribute to a list of strings that contain
	 * the values of the element. Use to store the
     * child elements representing features of this out-of-typesystem element.
     */
    std::map<std::string, std::vector<std::string>* > childElements;

	OotsElementData() : elementName(0) {}

	~OotsElementData() {
	  if (elementName != NULL) {
	    delete elementName;
		elementName=0;
	  }
	  for (size_t i=0; i < attributes.size();i++) {
		if (attributes.at(i) != NULL) {
	      delete attributes.at(i);
		}
	  }
	  std::map<std::string, std::vector<std::string>* >::iterator ite;
	  for (ite=childElements.begin(); ite != childElements.end();ite++) {
	    if (ite->second != NULL) {
		  delete ite->second;
		}
	  }
    }
  };
  
  /** 
   * Data structure holding the index and the xmi:id of an array or list element that
   * is a reference to an out-of-typesystem FS.
   */
  class XmiArrayElement {
  public:
    int index;
    int xmiId;

    XmiArrayElement(int index, int xmiId) {
      this->index = index;
      this->xmiId = xmiId;
    }
  };
/**
 * Holds information that is shared between the XmiCasSerializer and the XmiCasDeserializer. This
 * allows consistency of XMI IDs across serializations, and also provides the ability to filter out
 * some FSs during serialization (e.g. to send to a service) and then reintegrate those FSs during
 * the next deserialization.
 * 
 */
class UIMA_LINK_IMPORTSPEC XmiSerializationSharedData {
  private:
  /**
   * A map from FeatureStructure address to XMI ID. This is built during deserialization, then used
   * by the next serialization to ensure consistent IDs.
   */
    std::map<int, int> fsAddrToXmiIdMap;
   /** 
   * A map from xmi:id to FeatureStructure address.  This is populated whenever
   * an XMI element is serialized or deserialized.  It is used by the
   * getFsAddrForXmiId() method, necessary to support merging multiple XMI
   * CASes into the same CAS object.
   **/
   std::map<int,int> xmiIdToFsAddrMap;
  
  /**
   * List of OotsElementData objects, each of which captures information about
   * incoming XMI elements that did not correspond to any type in the type system.
   */
  std::vector<OotsElementData*> ootsFs;
  
  /**
   * Map that from the xmi:id  Sofa to a List of xmi:id's  for
   * the out-of-typesystem FSs that are members of that Sofa's view.
   */
  std::map<int,std::vector<int>*> ootsViewMembers;

  /** Map from Feature Structure address (Integer) to OotsElementData object, capturing information 
   * about out-of-typesystem features that were part of an in-typesystem FS.  These include both
   * features not defined in the typesystem and features that are references to out-of-typesystem
   * elements.  This information needs to be included when the FS is subsequently serialized.
   */
  std::map<int, OotsElementData*> ootsFeatures;
  
  /** Map from Feature Structure address (Integer) of an FSArray to a list of 
   * {@link XmiArrayElement} objects, each of which holds an index and an xmi:id
   * for an out-of-typesystem array element.
   */
  std::map<int,std::vector<XmiArrayElement*>*> ootsArrayElements;
  

  /**
   * The maximum XMI ID used in the serialization. Used to generate unique IDs if needed.
   */
    int maxXmiId;

public:
  XmiSerializationSharedData() : maxXmiId(0) {
  }
  ~XmiSerializationSharedData() {
    for (size_t i=0; i < ootsFs.size(); i++) {
      if (ootsFs.at(i) != NULL) {
        delete ootsFs.at(i);
      }
    }

    std::map<int,std::vector<XmiArrayElement*>*>::iterator ite;
    for (ite = ootsArrayElements.begin(); ite != ootsArrayElements.end();ite++) {
      if (ite->second != NULL) {
        std::vector<XmiArrayElement*>* vec =  ite->second;
        for (size_t i=0; i < vec->size(); i++) {
          if (vec->at(i) != NULL) {
            delete vec->at(i);
          }
        }
        delete vec;
      }
    }

	std::map<int,std::vector<int>*>::iterator viewite;
	for (viewite = ootsViewMembers.begin(); 
		viewite != ootsViewMembers.end();viewite++) {
		if (viewite->second != NULL) {
			delete viewite->second;
		}
    }
	std::map<int, OotsElementData*>::iterator featite;
	for (featite = ootsFeatures.begin(); 
		featite != ootsFeatures.end();featite++) {
		if (featite->second != NULL) {
			delete featite->second;
		}
    }
  }

  void addIdMapping(int fsAddr, int xmiId) { 
    fsAddrToXmiIdMap[fsAddr] = xmiId;
    xmiIdToFsAddrMap[xmiId] = fsAddr;
    if (xmiId > maxXmiId)
      maxXmiId = xmiId;
  }

  int getXmiId(int fsAddr) {
    // see if we already have a mapping
    std::map<int,int>::iterator ite = fsAddrToXmiIdMap.find(fsAddr);
    if (ite != fsAddrToXmiIdMap.end()) {
      return ite->second;
    } else { // no mapping for this FS. Generate a unique ID
      // to be sure we get a unique Id, increment maxXmiId and use that
      fsAddrToXmiIdMap[fsAddr] = ++maxXmiId;
      xmiIdToFsAddrMap[maxXmiId] = fsAddr;
      return maxXmiId;
    }
  }
   /**
   * Gets the FS address that corresponds to the given xmi:id, in the most
   * recent serialization or deserialization.
   *   
   * @param xmiId an xmi:id from the most recent XMI CAS that was serialized
   *   or deserialized.
   * @return the FS address of the FeatureStructure corresponding to that
   *   xmi:id, -1 if none.
   */
  int getFsAddrForXmiId(int xmiId) {
	  std::map<int,int>::iterator ite =  xmiIdToFsAddrMap.find(xmiId);
	  if (ite != xmiIdToFsAddrMap.end() ) 
		  return ite->second;
	  else  {
		  //cout << __FILE__ << __LINE__ << " getFsAddrForXmiId() could not find xmiid " << xmiId << endl; 
      return -1;	   
			/**ErrorInfo errInfo;
		  errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
		  ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
		  msg.addParam("getFSAddrForXmiId Unknown xmiId");
		  msg.addParam(xmiId);
		  errInfo.setMessage(msg);
		  errInfo.setSeverity(ErrorInfo::unrecoverable);
		  ExcIllFormedInputError exc(errInfo);
		  throw exc;**/ 
	  }
  }
  
 

  /**
   * Records information about an XMI element that was not an instance of any type in the type system.
   * @param elemData information about the out-of-typesystem XMI element
   */
  void addOutOfTypeSystemElement(OotsElementData * elemData) {
    this->ootsFs.push_back(elemData);
    //check if we need to update max ID
    int xmiId = elemData->xmiId;
    if (elemData->xmiId > maxXmiId)
      maxXmiId = elemData->xmiId;
  }

  /**
   * Gets a List of {@link OotsElementData} objects, each of which describes an
   * incoming XMI element that did not correspond to a Type in the TypeSystem.
   * @return List of {@link OotsElementData} objects
   */
  std::vector<OotsElementData *> & getOutOfTypeSystemElements() {
    return this->ootsFs;
  }
  
  /**
   * Records that an out-of-typesystem XMI element should be a member of the
   * specified view.
   * @param sofaXmiId xmi:id of a Sofa
   * @param memberXmiId xmi:id of an out-of-typesystem element that should be
   *   a member of the view for the given Sofa
   */
  void addOutOfTypeSystemViewMember(int sofaXmiId, int memberXmiId) {
    std::vector<int> * memberList = 0; 
    std::map<int,std::vector<int>* >::iterator ite = this->ootsViewMembers.find(sofaXmiId);
    if (ite == ootsViewMembers.end() ) {
      memberList = new std::vector<int>;
      ootsViewMembers[sofaXmiId] = memberList;
    } else {
      memberList = ite->second;
    }
    memberList->push_back(memberXmiId);
  }
  
  /**
   * Gets a List of xmi:id's (Strings) of all out-of-typesystem XMI elements
   * that are members of the view with the given id.
   * @param sofaXmiId xmi:id of a Sofa
   * @return List of xmi:id's of members of the view for the given Sofa.
   */
  void getOutOfTypeSystemViewMembers(int sofaXmiId, std::vector<int>& tofill) {
    std::map<int, std::vector<int> *>::iterator ite = this->ootsViewMembers.find(sofaXmiId); 
    std::vector<int> * memberList = NULL;
    if (ite != ootsViewMembers.end()) {
      memberList = ite->second;
      for (size_t i=0;i < memberList->size();i++) {
        tofill.push_back(memberList->at(i));
      }
    }

  }
  
  /**
   * Records an out-of-typesystem attribute that belongs to an in-typesystem FS.
   * This will be added to the attributes when that FS is reserialized.
   * @param addr CAS address of the FS 
   * @param featName name of the feature
   * @param featVal value of the feature, as a string
   */
  void addOutOfTypeSystemAttribute(int addr, std::string featName, std::string featVal) {
    std::map<int, OotsElementData*>::iterator ite = this->ootsFeatures.find(addr);
    OotsElementData * oed = NULL;
    if (ite != ootsFeatures.end() )
      oed = ite->second;
    if (oed == NULL) {
      oed = new OotsElementData();
      this->ootsFeatures[addr] = oed;
    }
    oed->attributes.push_back(new XmlAttribute(featName, featVal));
  }  

  void addOutOfTypeSystemAttribute(int addr, icu::UnicodeString& featName, 
				   icu::UnicodeString & featVal) {
      //cout << "addOotsAttribute " << featName << "=" << featVal << endl;
      addOutOfTypeSystemAttribute(addr, ( (UnicodeStringRef)featName).asUTF8(),
        ( (UnicodeStringRef)featVal).asUTF8());
  }

  /**
   * Records out-of-typesystem child elements that belong to an in-typesystem FS.
   * These will be added to the child elements when that FS is reserialized.
   * @param addr CAS address of the FS 
   * @param featName name of the feature (element tag name)
   * @param featVal values of the feature, as a List of strings
   */
    void addOutOfTypeSystemChildElements(int addr, std::string featName, std::vector<std::string> featVals) {
      std::map<int, OotsElementData*>::iterator ite = this->ootsFeatures.find(addr);
      OotsElementData * oed = NULL;
      if (ite != ootsFeatures.end() )
        oed = ite->second;
      if (oed == NULL) {
        oed = new OotsElementData();
        this->ootsFeatures[addr] = oed;
      } 

      std::map<std::string, std::vector<std::string>*>::iterator ite2 = oed->childElements.find(featName);
      std::vector<std::string> * pVals = NULL;
      if (ite2 ==	oed->childElements.end() ) {
        pVals = new std::vector<std::string>;
        oed->childElements[featName] = pVals;
      } else {
        pVals = ite2->second;
      }

      for (size_t i = 0; i < featVals.size();i++) {
        pVals->push_back(featVals.at(i));
      }

    }  
  
  /**
   * Gets information about out-of-typesystem features that belong to an
   * in-typesystem FS.
   * @param addr CAS address of the FS
   * @return object containing information about out-of-typesystem features
   *   (both attributes and child elements)
   */
  OotsElementData * getOutOfTypeSystemFeatures(int addr) {
	  std::map<int, OotsElementData*>::iterator ite = this->ootsFeatures.find(addr);
	  if (ite != this->ootsFeatures.end())
		  return ite->second;
      else return NULL; 
  }
  
  /**
   * Get all FS Addresses that have been added to the id map.
   * @return an array containing all the FS addresses
   */
  void getAllFsAddressesInIdMap( std::vector<int> & tofill) {    
	  std::map<int,int>::iterator ite;
	  for (ite = this->fsAddrToXmiIdMap.begin(); ite != fsAddrToXmiIdMap.end();ite++) {
		  tofill.push_back(ite->first);
	  }
  }  
  
  /**
   * Gets information about out-of-typesystem array elements.
   * @param addr the CAS address of an FSArray
   * @return a List of {@link XmiArrayElement} objects, each of which
   *   holds the index and xmi:id of an array element that is a
   *   reference to an out-of-typesystem FS.
   */
  std::vector<XmiArrayElement*> * getOutOfTypeSystemArrayElements(int addr) {
	  std::map<int, std::vector<XmiArrayElement*>*>::iterator ite=this->ootsArrayElements.find(addr);
      if (ite != ootsArrayElements.end()) 
		  return ite->second;
	  else return NULL;
  }
  

  /**
   * Records an out-of-typesystem array element in the XmiSerializationSharedData.
   * @param addr CAS address of FSArray
   * @param index index into array 
   * @param xmiId xmi:id of the out-of-typesystem element that is the value at the given index
   */
  void addOutOfTypeSystemArrayElement(int addr, int index, int xmiId) {
    std::map<int, std::vector<XmiArrayElement*>* >::iterator ite = this->ootsArrayElements.find(addr);
    std::vector<XmiArrayElement*> * oed = NULL;
    if (ite != ootsArrayElements.end() )
      oed  = ite->second;
    else {
      oed = new std::vector<XmiArrayElement*>;
      this->ootsArrayElements[addr] = oed;
    }
    oed->push_back(new XmiArrayElement(index, xmiId));
  }


  void clearIdMap() {
      fsAddrToXmiIdMap.clear();
      xmiIdToFsAddrMap.clear();
      maxXmiId = 0;
  }

  void print() {
    std::map<int,OotsElementData *>::iterator ite;
    for (size_t i=0; i < ootsFs.size() ;i++ ) {
       OotsElementData * oed = ootsFs.at(i);
       std::cout << "**OotsFS " << i << oed->elementName->qualifiedName << std::endl;
       std::cout << "NUM CHILDELEMENTS " << oed->childElements.size() << std::endl;
       for (size_t i=0; i < oed->attributes.size();i++) {
         std::cout << oed->attributes.at(i)->name << " " << oed->attributes.at(i)->value << std::endl;
       }    
    }
  }

  /**
   * For debugging purposes only.
   */
  
  /**
  string toString() {
    
    stringstream str; 
 
    int[] keys = fsAddrToXmiIdMap;
    for (int i = 0; i < keys.length; i++) {
      buf.append(keys[i]).append(": ").append(fsAddrToXmiIdMap.get(keys[i])).append('\n');
    }
    return str.str();;
  }**/

};

}


/* ----------------------------------------------------------------------- */
/*       Implementation                                                    */
/* ----------------------------------------------------------------------- */


/* ----------------------------------------------------------------------- */


#endif
