/* -*- c++ -*- (enables emacs c++ mode) */
/*========================================================================

 Copyright (C) 2006-2009 Yves Renard, Julien Pommier.

 This file is a part of GETFEM++

 Getfem++ is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as
 published by the Free Software Foundation; version 2.1 of the License,
 or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Lesser General Public License for more details.
 You should have received a copy of the GNU Lesser General Public
 License along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301,
 USA.

 ========================================================================*/

/*
 * This is sample code generated by rpcgen.
 * These are only templates and you can use them
 * as a guideline for developing your own functions.
 */

#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include "gfi_rpc.h"
#include "getfem_interface.h"

void *
gfmrpc_null_1_svc(struct svc_req *rqstp)
{
        static char * result;

        /*
         * insert server code here
         */
        return (void *) &result;
}

void*
gfmrpc_chdir_1_svc(char *cwd, struct svc_req *rqstp)
{
  static char * result;
  chdir(cwd);
  return (void *) &result;
}

/*
char* getfem_interface_main(int config_id, const char *function, 
			    int nb_in_args,
			    const gfi_array *in_args[], 
			    int *nb_out_args,
			    gfi_array ***pout_args, char **pinfomsg);
*/
gfi_output *
gfmrpc_call_1_svc(int config_id, char *funname, gfi_array_list in, int nlhs,  struct svc_req *rqstp)
{
  static gfi_output  result;
  static int cnt = 0;
  static char *infomsg = 0;
  unsigned int i;
  gfi_array **pin;
  gfi_array **pout = NULL;
  static char *errmsg = 0;
  //printf("** CALLED FUNCTION gf_%s(", funname);

  if (cnt++) {
    if (result.status == GFI_STATUS_OK) {
      for (i=0; i < result.gfi_output_u.output.arg.arg_len; ++i) {
	gfi_array *t = &result.gfi_output_u.output.arg.arg_val[i];
	//if (gfi_array_get_class(t) == GFI_OBJID) printf("cleaning gfi_array %p\n", gfi_objid_get_data(t));
        gfi_array_destroy(t);
      }
      free(result.gfi_output_u.output.arg.arg_val);
    }
    if (infomsg) { free(infomsg); infomsg = 0; }
    if (errmsg) free(errmsg);
  }

  pin = calloc(in.arg.arg_len, sizeof(gfi_array*));
  for (i=0; i < in.arg.arg_len; ++i) {
    pin[i] = &in.arg.arg_val[i];
    //printf("%s%s", i?",":"", gfi_array_get_class_name(pin[i]));
  }
  //printf(")\n");
  /*  for (i=0; i < in.arg.arg_len; ++i) {
    printf("arg %d: ", i+1);
    gfi_array_print(pin[i]);
    }*/
  /* pout = calloc(nlhs == 0 ? 1 : nlhs, sizeof(gfi_array*)); */
  errmsg = getfem_interface_main(config_id, funname, in.arg.arg_len, (const gfi_array**)pin, &nlhs, &pout, &infomsg);
  if (infomsg == NULL) infomsg = strdup(""); /* or xdr will complain */
  result.infomsg = infomsg;
  if (errmsg) {
    printf("%s : error: %s\n", funname, errmsg);
    result.status = GFI_STATUS_ERROR;
    result.gfi_output_u.errmsg = errmsg;
  } else {
    result.status = GFI_STATUS_OK;
    result.gfi_output_u.output.arg.arg_len = nlhs;
    /*printf("%s : return %d arguments\n", funname, nlhs);*/
    result.gfi_output_u.output.arg.arg_val = calloc(nlhs, sizeof(gfi_array));
    
    for (i=0; i < nlhs; ++i) {
      assert(pout[i]);
      /*if (gfi_array_get_class(pout[i]) == GFI_OBJID)
	printf("result [%d] = %p %p\n", i, pout[i], gfi_objid_get_data(pout[i]));*/
      result.gfi_output_u.output.arg.arg_val[i] = *pout[i];
      free(pout[i]);
    }
  }
  if (pout) free(pout);
  free(pin);
  return &result;
}
