##
## 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.
##

// This file automatically generated by:
//   $version
//   $now
// This file is automatically created and should not be edited!

#set($i = $intf.name())
#set( $vf = "ValueFactory$intf.name()" )

\#include "$inc"
\#include "${intf.name()}.h"
\#include "Stub${i}Server.h"
\#include "Stub${i}Client.h"
\#include "common/EtchError.h"
\#include "serialization/EtchField.h"
\#include "serialization/EtchAsyncMode.h"
\#include "serialization/EtchDirection.h"
\#include "serialization/EtchValidators.h"
\#include "serialization/EtchImportExportHelper.h"

using namespace $namespace;

status_t $vf::Etch${intf.name()}RuntimeListener::onRuntimeChanged(EtchRuntime* runtime) {
  if (runtime == NULL) {
    return ETCH_ERROR;
  }
  if (runtime->isClosed()) {
    //the runtime is closed and is removed
    $vf::SRuntimes.remove(runtime->getId());
  }
  return ETCH_OK;
}

capu::Mutex $vf::SRuntimesMutex;
capu::List<capu::uint64_t> $vf::SRuntimes;
$vf::Etch${intf.name()}RuntimeListener $vf::S${intf.name()}RuntimeListener;

##--------------------------------------------------------------
## Classes that represent anonym creation in java
##--------------------------------------------------------------
#foreach ( $n in $intf.iterator() )
#if ($n.isStruct() || $n.isExcept())
#set( $tname = $n.efqname( $helper ) )
class ImportExportHelper$n.vname($helper)
  : public EtchImportExportHelper {
public:
  ImportExportHelper$n.vname($helper)(EtchRuntime* runtime) 
  : EtchImportExportHelper(runtime) {
  }

  virtual ~ImportExportHelper$n.vname($helper)() {
  }
  
  status_t exportValue(EtchValueFactory* vf, EtchObjectPtr value, EtchStructValue *&result)
  {
    EtchStructValue* _struct = new EtchStructValue( $vf::${n.vname( $helper )}, vf );
    $i::${tname}Ptr v = capu::smartpointer_cast<$i::$tname>(value);
#set($CountParams = 0)
#foreach( $p in $n.getAllParameters() )
#set($CountParams = $CountParams + 1)
    EtchObjectPtr val$CountParams = v->$helper.getGetterName($p.name())();
    _struct->put($vf::$p.vname($helper)(), val$CountParams );
#end
    result = _struct;
    ETCH_LOG_TRACE(mRuntime->getLogger(), mRuntime->getLogger().getDeliveryServiceContext(), "Valuefactory ${namespace}: exported $n.vname($helper) Value.");
    return ETCH_OK;
  }
  status_t importValue(EtchStructValue* value, EtchObjectPtr &result)
  {
    $i::$tname* v = new $i::${tname}();
#set($CountParams = 0)
#foreach ($p in $n.getAllParameters())
#set($CountParams = $CountParams + 1)
    $helper.getEtchTypeName($p.type(), true) tmp$CountParams;
    EtchObjectPtr val$CountParams;
    value->get($vf::$p.vname($helper)(), &val$CountParams);
    tmp$CountParams = capu::smartpointer_cast<$helper.getEtchTypeName($p.type(), false)>(val$CountParams);
    v->$helper.getSetterName($p.name())(tmp$CountParams);
#end
    result = v;
    ETCH_LOG_TRACE(mRuntime->getLogger(), mRuntime->getLogger().getDeliveryServiceContext(), "Valuefactory ${namespace}: imported $n.vname($helper) Value.");
    return ETCH_OK;
  }
};
#elseif ($n.isExtern())
#set( $tname = $n.efqname( $helper ) )
#elseif ($n.isEnumx())
#set( $tname = $n.efqname( $helper ) )
    
class ImportExportHelper$n.vname( $helper ) 
: public EtchImportExportHelper {  
public:
  ImportExportHelper$n.vname($helper)(EtchRuntime* runtime) 
  : EtchImportExportHelper(runtime) {
  }

  virtual ~ImportExportHelper$n.vname($helper)() {
  }

  status_t exportValue(EtchValueFactory* vf, EtchObjectPtr value, EtchStructValue *&result)
  {
     EtchStructValue* _struct = new EtchStructValue( $vf::${n.vname( $helper )}, vf );
     ${tname}Ptr v = capu::smartpointer_cast<${tname}>(value);
     switch (v->Value)
     {
#foreach ($p in $n.iterator())
       case $tname::${tname}_$p.name(): _struct->put($vf::$p.vname($helper)(), new EtchBool(true) ); break;
#end
     }
     result = _struct;
     return ETCH_OK;
   }

   status_t importValue(EtchStructValue* value, EtchObjectPtr &result)
   {
     // if empty, it likely means that a null value was sent
     // or an unknown key (from a different rev of the service).
     if (value->isEmpty())
       return ETCH_EINVAL;

     // there should only be a single key, so take the first one
     EtchHashTable<EtchField, capu::SmartPointer<EtchObject> >::ConstIterator it = value->begin();
     EtchHashTable<EtchField, capu::SmartPointer<EtchObject> >::HashTableEntry entry;
     it.next(&entry);
     EtchField key = entry.key;
#foreach ($p in $n.iterator())
     if (key.equals(&$vf::$p.vname($helper)()))
     {
       result = new ${tname}(${tname}::${tname}_$p.name());
       return ETCH_OK;
     }
#end

     // a known key was sent, but it did not match any defined
     // key for this type.
     return ETCH_ENOT_EXIST;
   }
};
#end
#end


//Static Variable Initialization
EtchTypeMap* $vf::types() {
static EtchTypeMap ret;
return &ret;
}

EtchClass2TypeMap* $vf::class2type() {
static EtchClass2TypeMap ret;
return &ret;
}

#foreach ( $n in $intf.iterator() )
#if ($n.isEnumx() || $n.isStruct() || $n.isExtern() || $n.isExcept() || $n.isMessage())
EtchType* $vf::$n.vname( $helper );
#end
#end

#set( $x = $params.clear() )
## standard params from DefaultValueFactory
#set( $x = $params.add( "msg" ) )
#set( $x = $params.add( "result" ) )
#foreach( $n in $intf.iterator() )
#if ($n.isEnumx() || $n.isStruct() || $n.isExcept() || $n.isMessage())
#foreach( $param in $n.iterator() )
#if (!$params.contains($param.name().name()))
#set( $x = $params.add($param.name().name()) )

EtchField& $vf::$param.vname( $helper )() {
  static EtchField ret("$param.name().name()");
  return ret;
}
#end
#end
#end
#end

${vf}::${vf}( EtchString uri ) : EtchDefaultValueFactory(uri, types(), class2type())
{
#foreach ( $n in $intf.iterator() )
#if ($n.isMixin())
#set( $m = $n.getModule() )
#set( $s = $m.iterator().next() )
  addMixin( new ${m.name()}.ValueFactory${s.name()}( uri ) );
#end
#end
}

status_t ${vf}::InitTypes()
{
#foreach ( $n in $intf.iterator() )
#if ($n.isEnumx() || $n.isStruct() || $n.isExtern() || $n.isExcept() || $n.isMessage())
  types()->get(EtchString("$n.fqname()"), ${vf}::${n.vname( $helper )});
#end
#end
  return ETCH_OK;
}

status_t ${vf}::InitResults()
{
#foreach ( $n in $intf.iterator() )
#if ($n.isMessage())
  ${vf}::${n.vname( $helper )}->setDirection((EtchDirection)$n.msgDir());
#if (!$n.isHidden())
#if ($n.isQueuedAsyncReceiver())
  ${vf}::${n.vname( $helper )}->setAsyncMode((EtchAsyncMode)QUEUED);
#elseif ($n.isFreeAsyncReceiver())
  ${vf}::${n.vname( $helper )}->setAsyncMode((EtchAsyncMode)FREE);
#else
  ${vf}::${n.vname( $helper )}->setAsyncMode((EtchAsyncMode)NONE);
#end
#if (!$n.isOneway())
#set( $r = $n.getResultMessage() )
  ${vf}::${n.vname( $helper )}->setResult(${vf}::$r.vname( $helper ));
  ${vf}::${r.vname( $helper )}->setTimeout($n.getTimeout());
#end
#end
#end
#end
  return ETCH_OK;
}

## ----------------------------- import / export -----------------------------
status_t ${vf}::InitImportExport(EtchRuntime* runtime)
{
#foreach ( $n in $intf.iterator() )
#if ($n.isStruct() || $n.isExcept())
#set( $tname = $n.efqname( $helper ) )
  $vf::class2type()->put($intf.name()::${tname}::TYPE(), $vf::${n.vname($helper)});
  $vf::${n.vname( $helper )}->setComponentType($i::${tname}::TYPE());
#if ($n.hasExtends())
  $vf::${n.vname($helper)}->setSuperType($n.getExtends().vname($helper));
#end
  $vf::${n.vname($helper)}->setImportExportHelper(new ImportExportHelper$n.vname($helper)(runtime));
#elseif ($n.isExtern())
#set( $tname = $n.efqname( $helper ) )
#elseif ($n.isEnumx())
#set( $tname = $n.efqname( $helper ) )
  $vf::class2type()->put(${tname}::TYPE(), $vf::${n.vname($helper)});
  $vf::${n.vname( $helper )}->setComponentType(${tname}::TYPE());
  $vf::${n.vname( $helper )}->setImportExportHelper(new ImportExportHelper$n.vname($helper)(runtime));
#end
#end

  return ETCH_OK;
}

## ----------------------------- fields -----------------------------

status_t ${vf}::InitFields()
{
#set( $x = $params.clear() )
## standard params from DefaultValueFactory
#set( $x = $params.add( "msg" ) )
#set( $x = $params.add( "result" ) )
#foreach ( $n in $intf.iterator() )
#if ($n.isMessage())
#if (!$n.isHidden())
#if (!$n.isOneway())
#set( $r = $n.getResultMessage() )
  $vf::${r.vname( $helper )}->setResponseField( $vf::_mf_result() );
#end
#end
#end
#end
  return ETCH_OK;
}


#set( $ctr = 0 )
status_t $vf::InitParams(EtchRuntime* runtime)
{
  capu::SmartPointer<EtchValidator> tmpValue;
#foreach( $n in $intf.iterator() )
#if ($n.isEnumx() || $n.isStruct() || $n.isExcept() || $n.isMessage())
#if ($ctr > 0 && $ctr % 10 == 0)

  $vf::InitParams${ctr}(runtime);

  return ETCH_OK;
}

status_t $vf::InitParams${ctr}(EtchRuntime* runtime)
{
  capu::SmartPointer<EtchValidator> tmpValue;
#end
#set( $ctr = $ctr + 1 )
  

  // params for $n.name()
#if ($n.isStruct() || $n.isExcept())
#foreach( $param in $n.getAllParameters() )
  $helper.getValidator($param);
  $vf::${n.vname( $helper )}->putValidator($vf::$param.vname($helper)(), tmpValue);

#end ## -- foreach --
#else
#foreach( $param in $n.iterator() )
  $helper.getValidator($param);
  $vf::${n.vname( $helper )}->putValidator($vf::$param.vname($helper)(), tmpValue);

#end ## -- foreach --
#end ## -- else --
#if ($n.isMessage())
  EtchValidatorLong::Get(runtime, 0, tmpValue);
  ${n.vname( $helper )}->putValidator($vf::_mf__messageId(), tmpValue);

#if ($n.isHidden())
#set( $param = $n.getResultParam() )
#set( $reqMsg = $n.getRequestMessage() )
#foreach( $t in $reqMsg.thrown().iterator() )
  $helper.getValidator($t)
  $vf::${n.vname( $helper )}->putValidator($vf::$param.vname($helper)(), tmpValue); // thrown $t.name()

#end ## -- foreach --
  EtchValidatorRuntimeException::Get(runtime, tmpValue);
  $vf::${n.vname( $helper )}->putValidator($vf::$param.vname($helper)(), tmpValue); // thrown RuntimeException
  EtchValidatorLong::Get(runtime, 0, tmpValue);
  $vf::${n.vname( $helper )}->putValidator($vf::_mf__inReplyTo(), tmpValue);
#end ## -- isHidden --
#end ## -- isMessage --
#end ## -- $n.isEnumx() || $n.isStruct() || $n.isExcept() || $n.isMessage() --
#end ## -- foreach --

  return ETCH_OK;
}

status_t $vf::InitValueFactory(EtchRuntime* runtime)
{
  status_t status;
  SRuntimesMutex.lock();
  if (SRuntimes.find(runtime->getId()) != SRuntimes.end()) {
    //runtime is already in list
    SRuntimesMutex.unlock();
    return ETCH_OK;
  }

  status = SRuntimes.push_back(runtime->getId());
  runtime->registerListener(&S${i}RuntimeListener);
  if (status != ETCH_OK) {
    SRuntimesMutex.unlock();
    return status;
  }

  if (SRuntimes.size() > 1) {
    //Valuefactory is already initialized
    SRuntimesMutex.unlock();
    return ETCH_OK;
  }
  SRuntimesMutex.unlock();
  
  status = $vf::Init(runtime, types(), class2type());
  if (status != ETCH_OK) {
    return status;
  }
  
  status = $vf::InitTypes();
  if (status != ETCH_OK) {
    return status;
  }
  
  status = $vf::InitResults();
  if (status != ETCH_OK) {
    return status;
  }
  
  status = $vf::InitFields();
  if (status != ETCH_OK) {
    return status;
  }
#foreach( $n in $intf.iterator() )
#if ($n.isExtern())
    status = ${n.sname( $helper )}.Init(runtime, ${n.vname($helper)}(), class2type);
    if (status != ETCH_OK) {
      return status;
    }
#end
#end
  status = $vf::InitParams(runtime);
  if (status != ETCH_OK) {
    return status;
  }
  
  status = $vf::InitImportExport(runtime);
  if (status != ETCH_OK) {
    return status;
  }

  status = Stub${i}<void>::Init(runtime);
  if (status != ETCH_OK) {
    return status;
  }
  
  status = Stub${i}Server::Init(runtime);
  if (status != ETCH_OK) {
    return status;
  }
  
  status = Stub${i}Client::Init(runtime);
  if (status != ETCH_OK) {
    return status;
  }

  // done updating types, and class2type: lock them.
  types()->lock();
  class2type()->lock();
  
  return ETCH_OK;
}

status_t $vf::getNativeArrayForComponentType(const EtchObjectType *objectType,  capu::SmartPointer<EtchNativeArrayBase> &nativeArray, capu::int32_t length, capu::int32_t dim) {
#foreach ( $n in $intf.iterator() )
#if ($n.isStruct())
#set( $tname = $n.efqname( $helper ) )
  if (objectType == $i::${tname}::TYPE()) {
    nativeArray =  new EtchNativeArray<capu::SmartPointer<$i::${tname}> >(length, dim);
    return ETCH_OK;
  }
#end
#end
  return ETCH_ERROR;
}