#include "torture.h"
#include "torture-compare.h"

/*** App-specific servant structures ***/
typedef struct {
  POA_Torture servant;
  PortableServer_POA poa;

} impl_POA_Torture;

/*** Implementation stub prototypes ***/
static void impl_Torture__destroy(impl_POA_Torture * servant,
				  CORBA_Environment * ev);
CORBA_char *
impl_Torture_doString(impl_POA_Torture * servant,
		      CORBA_char * inparam,
		      CORBA_char ** outparam,
		      CORBA_char ** inoutparam,
		      CORBA_Environment * ev);

CORBA_octet
impl_Torture_doOctet(impl_POA_Torture * servant,
		     CORBA_octet inparam,
		     CORBA_octet outparam,
		     CORBA_octet * inoutparam,
		     CORBA_Environment * ev);

CORBA_short
impl_Torture_doShort(impl_POA_Torture * servant,
		     CORBA_short inparam,
		     CORBA_short * outparam,
		     CORBA_short * inoutparam,
		     CORBA_Environment * ev);

CORBA_long
impl_Torture_doLong(impl_POA_Torture * servant,
		    CORBA_long inparam,
		    CORBA_long * outparam,
		    CORBA_long * inoutparam,
		    CORBA_Environment * ev);

Torture_SFixed
impl_Torture_doSFixed(impl_POA_Torture * servant,
		      Torture_SFixed * inparam,
		      Torture_SFixed * outparam,
		      Torture_SFixed * inoutparam,
		      CORBA_Environment * ev);

Torture_SVar *
impl_Torture_doSVar(impl_POA_Torture * servant,
		    Torture_SVar * inparam,
		    Torture_SVar ** outparam,
		    Torture_SVar * inoutparam,
		    CORBA_Environment * ev);

Torture_UFixed *
impl_Torture_doUFixed(impl_POA_Torture * servant,
		      Torture_UFixed * inparam,
		      Torture_UFixed ** outparam,
		      Torture_UFixed * inoutparam,
		      CORBA_Environment * ev);

Torture_UVar *
impl_Torture_doUVar(impl_POA_Torture * servant,
		    Torture_UVar * inparam,
		    Torture_UVar ** outparam,
		    Torture_UVar * inoutparam,
		    CORBA_Environment * ev);

Torture_Seq *
impl_Torture_doSeq(impl_POA_Torture * servant,
		   Torture_Seq * inparam,
		   Torture_Seq ** outparam,
		   Torture_Seq * inoutparam,
		   CORBA_Environment * ev);

Torture_AFixed_slice *
impl_Torture_doAFixed(impl_POA_Torture * servant,
		      Torture_AFixed inparam,
		      Torture_AFixed outparam,
		      Torture_AFixed inoutparam,
		      CORBA_Environment * ev);

Torture_AVar_slice *
impl_Torture_doAVar(impl_POA_Torture * servant,
		    Torture_AVar inparam,
		    Torture_AVar_slice ** outparam,
		    Torture_AVar inoutparam,
		    CORBA_Environment * ev);

CORBA_char *
impl_Torture_doTheWorks(impl_POA_Torture * servant,
			CORBA_short p1,
			CORBA_Object obj,
			CORBA_char achar,
			CORBA_Environment * ev);

/*** epv structures ***/
static PortableServer_ServantBase__epv impl_Torture_base_epv =
{
  NULL,			/* _private data */
  (gpointer) & impl_Torture__destroy,	/* finalize routine */
  NULL,			/* default_POA routine */
};
static POA_Torture__epv impl_Torture_epv =
{
  NULL,			/* _private */
  (gpointer) & impl_Torture_doString,

  (gpointer) & impl_Torture_doOctet,

  (gpointer) & impl_Torture_doShort,

  (gpointer) & impl_Torture_doLong,

  (gpointer) & impl_Torture_doSFixed,

  (gpointer) & impl_Torture_doSVar,

  (gpointer) & impl_Torture_doUFixed,

  (gpointer) & impl_Torture_doUVar,

  (gpointer) & impl_Torture_doSeq,

  (gpointer) & impl_Torture_doAFixed,

  (gpointer) & impl_Torture_doAVar,

  (gpointer) & impl_Torture_doTheWorks,

};

/*** vepv structures ***/
static POA_Torture__vepv impl_Torture_vepv =
{
  &impl_Torture_base_epv,
  &impl_Torture_epv,
};

/*** implementations ***/
#define ev_assert() g_assert(ev->_major == CORBA_NO_EXCEPTION)
#define ev_assert_exp(v) g_assert((v) && (ev->_major == CORBA_NO_EXCEPTION))

static Torture
Torture__create(PortableServer_POA poa, CORBA_Environment * ev)
{
  Torture retval;
  impl_POA_Torture *newservant;
  PortableServer_ObjectId *objid;

  newservant = g_new0(impl_POA_Torture, 1);
  newservant->servant.vepv = &impl_Torture_vepv;
  newservant->poa = poa;
  POA_Torture__init((PortableServer_Servant) newservant, ev);
  objid = PortableServer_POA_activate_object(poa, newservant, ev);
  CORBA_free(objid);
  retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);

  return retval;
}

int
main(int argc, char *argv[])
{
  CORBA_ORB orb;
  PortableServer_POA poa;
  CORBA_Environment *ev, ev_;
  Torture serv;
  CORBA_char *ior;

  ev = &ev_;
  CORBA_exception_init(ev);

  ORBit_Trace_setLevel(TraceLevel_Debug);
  orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
  ORBit_Trace_setLevel(TraceLevel_Debug);

  ev_assert_exp(orb);

  poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references(orb, "RootPOA", ev);
  ev_assert_exp(poa);
  PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(poa, ev),
				     ev);

  serv = Torture__create(poa, ev);
  ev_assert_exp(serv);

  ior = CORBA_ORB_object_to_string(orb, serv, ev);
  ev_assert_exp(ior);

  g_print("%s\n", ior);
  fflush(stdout);

  CORBA_free(ior);

  CORBA_ORB_run(orb, ev);
  
  return 0;
}

/* You shouldn't call this routine directly without first deactivating the servant... */
static void
impl_Torture__destroy(impl_POA_Torture * servant, CORBA_Environment * ev)
{

  POA_Torture__fini((PortableServer_Servant) servant, ev);
  g_free(servant);
}

CORBA_char *
impl_Torture_doString(impl_POA_Torture * servant,
		      CORBA_char * inparam,
		      CORBA_char ** outparam,
		      CORBA_char ** inoutparam,
		      CORBA_Environment * ev)
{
  CORBA_char *retval;

  DCK(String, inparam, PIN);
  DCK(String, *inoutparam, PIOIN);

  CORBA_free(*inoutparam);

  GEP(String, *outparam, POUT);
  GEP(String, *inoutparam, PIOOUT);
  GEP(String, retval, PRET);

  return retval;
}

CORBA_octet
impl_Torture_doOctet(impl_POA_Torture * servant,
		     CORBA_octet inparam,
		     CORBA_octet outparam,
		     CORBA_octet * inoutparam,
		     CORBA_Environment * ev)
{
  CORBA_octet retval;

  DCK(Octet, inparam, PIN);
  DCK(Octet, *inoutparam, PIOIN);

  GEP(Octet, *outparam, POUT);
  GEP(Octet, *inoutparam, PIOOUT);
  GEP(Octet, retval, PRET);

  return retval;
}

CORBA_short
impl_Torture_doShort(impl_POA_Torture * servant,
		     CORBA_short inparam,
		     CORBA_short * outparam,
		     CORBA_short * inoutparam,
		     CORBA_Environment * ev)
{
  CORBA_short retval;

  DCK(Short, inparam, PIN);
  DCK(Short, *inoutparam, PIOIN);

  GEP(Short, *outparam, POUT);
  GEP(Short, *inoutparam, PIOOUT);
  GEP(Short, retval, PRET);

  return retval;
}

CORBA_long
impl_Torture_doLong(impl_POA_Torture * servant,
		    CORBA_long inparam,
		    CORBA_long * outparam,
		    CORBA_long * inoutparam,
		    CORBA_Environment * ev)
{
  CORBA_long retval;

  DCK(Long, inparam, PIN);
  DCK(Long, *inoutparam, PIOIN);

  GEP(Long, *outparam, POUT);
  GEP(Long, *inoutparam, PIOOUT);
  GEP(Long, retval, PRET);

  return retval;
}

Torture_SFixed
impl_Torture_doSFixed(impl_POA_Torture * servant,
		      Torture_SFixed * inparam,
		      Torture_SFixed * outparam,
		      Torture_SFixed * inoutparam,
		      CORBA_Environment * ev)
{
  Torture_SFixed retval;

  return retval;
}

Torture_SVar *
impl_Torture_doSVar(impl_POA_Torture * servant,
		    Torture_SVar * inparam,
		    Torture_SVar ** outparam,
		    Torture_SVar * inoutparam,
		    CORBA_Environment * ev)
{
  Torture_SVar *retval;

  return retval;
}

Torture_UFixed *
impl_Torture_doUFixed(impl_POA_Torture * servant,
		      Torture_UFixed * inparam,
		      Torture_UFixed ** outparam,
		      Torture_UFixed * inoutparam,
		      CORBA_Environment * ev)
{
  Torture_UFixed *retval;

  return retval;
}

Torture_UVar *
impl_Torture_doUVar(impl_POA_Torture * servant,
		    Torture_UVar * inparam,
		    Torture_UVar ** outparam,
		    Torture_UVar * inoutparam,
		    CORBA_Environment * ev)
{
  Torture_UVar *retval;

  return retval;
}

Torture_Seq *
impl_Torture_doSeq(impl_POA_Torture * servant,
		   Torture_Seq * inparam,
		   Torture_Seq ** outparam,
		   Torture_Seq * inoutparam,
		   CORBA_Environment * ev)
{
  Torture_Seq *retval;

  return retval;
}

Torture_AFixed_slice *
impl_Torture_doAFixed(impl_POA_Torture * servant,
		      Torture_AFixed inparam,
		      Torture_AFixed outparam,
		      Torture_AFixed inoutparam,
		      CORBA_Environment * ev)
{
  Torture_AFixed_slice *retval;

  return retval;
}

Torture_AVar_slice *
impl_Torture_doAVar(impl_POA_Torture * servant,
		    Torture_AVar inparam,
		    Torture_AVar_slice ** outparam,
		    Torture_AVar inoutparam,
		    CORBA_Environment * ev)
{
  Torture_AVar_slice *retval;

  return retval;
}

CORBA_char *
impl_Torture_doTheWorks(impl_POA_Torture * servant,
			CORBA_short p1,
			CORBA_Object obj,
			CORBA_char achar,
			CORBA_Environment * ev)
{
  CORBA_char *retval;

  return retval;
}
