/** \file config_param.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.

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

    \brief MetaDataObjects for configuration parameters and values

   Description:

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


   01/30/2003  Initial creation

-------------------------------------------------------------------------- */
#ifndef UIMA_CONFIG_PARAM_HPP
#define UIMA_CONFIG_PARAM_HPP
// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------

#include "uima/pragmas.hpp" //must be first to surpress warnings
#include "uima/err_ids.h"
#include "uima/taemetadata.hpp"
#include "uima/strconvert.hpp"
#include "uima/exceptions.hpp"
#include <map>
namespace uima {
  UIMA_EXC_CLASSDECLARE(ConfigException, Exception);
  UIMA_EXC_CLASSDECLARE(ConfigParamException, ConfigException);

  /**
  * Contains the definition of a configuration parameter, for example
  * its name and its type.
  */
  class UIMA_LINK_IMPORTSPEC ConfigurationParameter : public MetaDataObject {
  public:
    enum EnParameterType {
      STRING, INTEGER, FLOAT, BOOLEAN
    };
    enum EnParameterAggregation {
      SINGLE_VALUE = false, MULTIPLE_VALUES = true
    };
    ConfigurationParameter()
        :MetaDataObject(), iv_name(), iv_description(), iv_enParamAggregation(SINGLE_VALUE),
        iv_mandatory(false), iv_vecRestrictedToDelegates() {}


    TyErrorId setName(const icu::UnicodeString  & name) {
      if (! isModifiable()) {
        return UIMA_ERR_CONFIG_OBJECT_COMITTED;
      }
      iv_name = name;
      return UIMA_ERR_NONE;
    }

    const icu::UnicodeString & getName() const {
      return iv_name;
    }

    TyErrorId setDescription(const icu::UnicodeString  & description) {
      if (! isModifiable()) {
        return UIMA_ERR_CONFIG_OBJECT_COMITTED;
      }
      iv_description = description;
      return UIMA_ERR_NONE;
    }

    const icu::UnicodeString & getDescription() const {
      return iv_description;
    }

    TyErrorId setType(EnParameterType enParamType) {
      if (! isModifiable()) {
        return UIMA_ERR_CONFIG_OBJECT_COMITTED;
      }
      iv_enParamType = enParamType;
      return UIMA_ERR_NONE;
    }

    EnParameterType getType() const {
      return iv_enParamType;
    }

    TyErrorId setMultiValued(EnParameterAggregation enMode) {
      if (! isModifiable()) {
        return UIMA_ERR_CONFIG_OBJECT_COMITTED;
      }
      iv_enParamAggregation = enMode;
      return UIMA_ERR_NONE;
    }

    bool isMultiValued() const {
      return(iv_enParamAggregation == MULTIPLE_VALUES);
    }

    TyErrorId setMandatory(bool man) {
      if (! isModifiable()) {
        return UIMA_ERR_CONFIG_OBJECT_COMITTED;
      }
      iv_mandatory = man;
      return UIMA_ERR_NONE;
    }

    bool isMandatory() const {
      return iv_mandatory;
    }

    /**
    * Returns true iff settings for this configuration parameter
    * will only be visible to certain delegate TAEs
    **/
    /*       bool hasRestrictions() const{                       */
    /*          return(iv_vecRestrictedToDelegates.size() != 0); */
    /*       }                                                   */

    /**
    * Settings for this configuration parameter will only be visible 
    * for the delegate AnC <code>delegateName</code> 
    **/
    TyErrorId addRestriction(const icu::UnicodeString & delegateName) {
      if (! isModifiable()) {
        return UIMA_ERR_CONFIG_OBJECT_COMITTED;
      }

      iv_vecRestrictedToDelegates.push_back(delegateName);
      return UIMA_ERR_NONE;
    }

    bool isDefinedForAnnotatorContext(const icu::UnicodeString & ancKey) const;

    /**
    * @return The names for the delegate TAEs which are possibly affected by
    * setting this parameter. If the vector is empty, all delegates
    * are possibly affected.
    **/
    /*       const std::vector<icu::UnicodeString> & getRestrictions() const{ */
    /*          return iv_vecRestrictedToDelegates;                           */
    /*       }                                                                */

  private:
    icu::UnicodeString iv_name;
    icu::UnicodeString iv_description;
    EnParameterType iv_enParamType;
    EnParameterAggregation iv_enParamAggregation;
    bool iv_mandatory;
    std::vector<icu::UnicodeString> iv_vecRestrictedToDelegates;


  }
  ; /* ConfigurationParameter */

  /**
  * Contains the value for a certain parameter. The parameter name is determined
  * by<code>getName()</code>.
  * Has several<code>extractValue</code>methods to extract the value according
  * to its type. These methods will return<code>UIMA_ERR_CONFIG_INVALID_EXRACTOR_FOR_TYPE</code>
  * if the value type does not match the type in the<code>extractValue</code>method.
  **/
  class UIMA_LINK_IMPORTSPEC NameValuePair : public MetaDataObject {

  public:
    typedef std::vector < icu::UnicodeString > TyStrValueList;
    typedef std::vector < int >                TyIntValueList;
    typedef std::vector < float >              TyFloatValueList;
    typedef std::vector < bool >               TyBoolValueList;

    NameValuePair();
    /**
    * Does nothing, as reconfiguration of parameter values is possible
    **/
    void commit() {}

    void setName(const icu::UnicodeString & name) {
      iv_name = name;
    }

    const icu::UnicodeString & getName() const {
      return iv_name;
    }

    void define(ConfigurationParameter::EnParameterType type, ConfigurationParameter::EnParameterAggregation enIsMulti);

    bool isMultiValued() const {
      return(iv_enAggregation == ConfigurationParameter::MULTIPLE_VALUES);
    }

    ConfigurationParameter::EnParameterType getType() const {
      return iv_enType;
    }

    // for single value
    TyErrorId               setValue(int value);
    TyErrorId               setValue(float value);
    TyErrorId               setValue(bool value);
    TyErrorId               setValue(const icu::UnicodeString & value);
    // for multiple value
    TyErrorId               addValue(int value);
    TyErrorId               addValue(float value);
    TyErrorId               addValue(bool value);
    TyErrorId               addValue(const icu::UnicodeString & value);

    bool                    extractBoolValue() const;
    vector<bool> const &    extractBoolValues() const;

    int                     extractIntValue() const;
    vector<int> const &     extractIntValues() const;

    float                   extractFloatValue() const;
    vector<float> const &   extractFloatValues() const;

    icu::UnicodeString const &          extractStringValue() const;
    vector<icu::UnicodeString> const &  extractStringValues() const;

    //Returns a  UTF-8 string
    std::string extractSingleByteStringValue() const;
    //converts array of values  from UTF-16 to UTF-8
    //Caller assumes memory ownership of string objects in vector
    void extractSingleByteStringValues( vector<std::string*> & values) const;


  private:
    size_t size() const;
    void ensureType(ConfigurationParameter::EnParameterType t) const;
    void ensureSingleValue() const;
    void ensureMultipleValues() const;
    void reset();
    std::string convert(const icu::UnicodeString & value) const;

    icu::UnicodeString iv_name;
    ConfigurationParameter::EnParameterType iv_enType;
    ConfigurationParameter::EnParameterAggregation iv_enAggregation;
    TyStrValueList    iv_strValues;
    TyIntValueList    iv_intValues;
    TyFloatValueList  iv_fltValues;
    TyBoolValueList   iv_boolValues;
  };

  /**
  * Contains all<code>ConfigurationParameter</code>objects for a certain configuration group.
  **/
  class UIMA_LINK_IMPORTSPEC ConfigurationGroup:public MetaDataObject {
  public:
    ConfigurationGroup()
        :MetaDataObject(), iv_configParams() {}

    ~ConfigurationGroup();

    void commit() {
      map<icu::UnicodeString, ConfigurationParameter *>::iterator entries;
      for (entries = iv_configParams.begin(); entries != iv_configParams.end(); entries++) {
        entries->second->commit();
      }
    }

    /**
    * Note: This object will assume memory ownership of<code>param</code>and will delete it in its
    * destructor !
    **/
    TyErrorId addConfigurationParameter(ConfigurationParameter * param) {
      if (! isModifiable()) {
        return UIMA_ERR_CONFIG_OBJECT_COMITTED;
      }
      iv_configParams[param->getName()] = param;
      return UIMA_ERR_NONE;
    }

    /**
    * returns TRUE iff a configuration parameter<code>paramName</code>exists in this group.
    **/
    bool hasConfigurationParameter(const icu::UnicodeString & paramName) const {
      map<icu::UnicodeString, ConfigurationParameter *>::const_iterator ite = iv_configParams.find(paramName);
      return(ite != iv_configParams.end());
    }

    /**
    * returns the <code>ConfigurationParameter</code> with name <code>paramName</code> or NULL
    * if no such parameter is found.
    **/
    const ConfigurationParameter * getConfigurationParameter(const icu::UnicodeString & paramName) const {
      map<icu::UnicodeString, ConfigurationParameter *>::const_iterator ite = iv_configParams.find(paramName);
      if (ite != iv_configParams.end()) {
        return ite->second;
      } else {
        return NULL;
      }
    }

    const vector <const ConfigurationParameter *> getConfigurationParameters() const;

  private:
    map<icu::UnicodeString, ConfigurationParameter *> iv_configParams;

  };

  /**
  * Contains all<code>NameValuePair</code>objects for a certain configuration group.
  **/
  class UIMA_LINK_IMPORTSPEC SettingsForGroup : public MetaDataObject {
  public:
    SettingsForGroup()
        :MetaDataObject(), iv_nameValuePairs() {}

    ~SettingsForGroup() {
      map<icu::UnicodeString, NameValuePair *>::iterator entries = iv_nameValuePairs.begin();
      while (entries != iv_nameValuePairs.end()) {
        delete (*entries).second;
        entries++;
      }

    }

    /**
    * Does nothing, as reconfiguration of parameter values is possible
    **/
    void commit() {}

    /**
    * Note: This object will assume memory ownership of<code>nvPair</code>and will delete it in its
    * destructor !
    **/
    void addNameValuePair(NameValuePair * nvPair) {
      NameValuePair * oldPair = getNameValuePair(nvPair->getName());
      if (EXISTS(oldPair)) {
        delete oldPair;
      }
      iv_nameValuePairs[nvPair->getName()] = nvPair;
    }

    /**
    * Returns the<code>NameValuePair</code>whose name equals<code>paramName</code>or NULL if no such object can be found.
    **/
    NameValuePair * getNameValuePair(const icu::UnicodeString & paramName) const {
      map<icu::UnicodeString, NameValuePair *>::const_iterator ite = iv_nameValuePairs.find(paramName);
      if (ite == iv_nameValuePairs.end()) {
        return NULL;
      } else {
        return(*ite).second;
      }
    }

    vector<NameValuePair const *> getNameValuePairs() const;

  private:
    map<icu::UnicodeString, NameValuePair *> iv_nameValuePairs;
  };


} // namespace uima
#endif
