/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * This software is the proprietary information of Sun Microsystems, Inc.
 * Use is subject to license terms.
 * 
 * Copyright 2004 Sun Microsystems, Inc.  Tous droits réservés.
 * Ce logiciel est propriété de Sun Microsystems, Inc.
 * Distribué par des licences qui en restreignent l'utilisation.
 *
 * ident        "@(#)Service_server.c 1.14     04/09/07 SMI"
 *
 */


/* File
 * ----
 * Service_server - JESMA standard header file
 *
 * Description
 * -----------
 *
 * This file contains the routines communication 
 * used by the rpc server 
 * 
 */

#include "Service.h"
#include <stdio.h>
#include <stdlib.h> 
#include <signal.h>

#include "mfRserver.h"
#include "mfConstant.h"



static AttValue att;             /* must be static   !*/
static AttValue_array att_array; /* must be a static !*/



extern int lookupResourceServer(/*in */ char * resourceName, /*out */ void *value );
extern  void castresource2string(char *value, int type,void *resource);



/*
 *
 * service_getattribute_1_svc
 *
 * This primitive is returning an attribute definition of a given 
 * resource knowing the attribute name
 *
 * input: 
 *       -resource_name:  name of the resource
 *       -attribute_name: name of the attribute
 *
 *     
 * return value: AttValue pointer      
 */ 
extern  AttValue * service_getattribute_1_svc(cstring resourceName, cstring attributeName, struct svc_req *rqstp) {
  void  *value;
  int type;
  int rc;

  DEBUG_PRINTF2(" service_getattribute: resource_name %s\n", resourceName);

  /*frees previous result */
  
  xdr_free((xdrproc_t) xdr_AttValue, (char *)  &att) ;

  att.value = (char *)    malloc(MF_ATTRIBUTE_NAME_SIZE);
  bzero(att.value, MF_ATTRIBUTE_NAME_SIZE);


  if (resourceName == NULL) {
      att.type = MF_TYPE_OBJECT_NOT_EXIST;
      DEBUG_PRINTF("service_getattribute: resourceName is a null parameter\n");
      return &att;
  }



  if (resourceName == NULL) {
      att.type = MF_TYPE_OBJECT_NOT_EXIST;
      DEBUG_PRINTF("service_getattribute: attributeName is a null parameter\n");
      return &att;
  }




  rc = mfGetResourceAttributePtr(resourceName,attributeName, &value, &type) ;


  printf(" mfGetResourceAttributePtr %rc = %d\n",rc);

  if (rc != MF_SUCCESS) {
    if (rc == MF_RESOURCE_OBJECT_NOT_EXIST) {
      att.type = MF_TYPE_OBJECT_NOT_EXIST;
      DEBUG_PRINTF3(" service_getattribute: resource_name %s not found rc=%d\n", resourceName, rc);
      return &att;
    } 


    if (rc == MF_RESOURCE_ATTRIBUTE_NOT_EXIST) {
      att.type = MF_TYPE_ATTRIBUTE_NOT_EXIST;
      DEBUG_PRINTF3(" service_getattribute: resource_name %s not found rc= %d\n", resourceName,rc );
      return &att;
    } 

 if (rc == MF_RESOURCE_GETTER_CALLBACK_NOT_EXIST) {
      att.type = MF_TYPE_CALLBACK_NOT_EXIST;
      DEBUG_PRINTF3(" service_getattribute: resource_name %s not found rc= %d\n", resourceName,rc);
      return &att;
    } 
  }
 
  /* perform the cast of the resource value, which is
     transformed into a char array in ptr->value */
  att.type=type;
  castresource2string(att.value,type, value); 

  DEBUG_PRINTF5(" service_getattribute:%s %s=%s , type = %d\n", resourceName,attributeName, att.value, att.type);
  
  return &att;

}


/*
 *
 * service_getattributes_1_svc
 *
 * This primitive is returning an attribute definition of a given 
 * resource knowing the attribute name
 *
 * input: 
 *       -resource_name:  name of the resource
 *       -arg2: array of name of the attribute
 *
 *     
 * return value: AttValue_arrray pointer      
 */ 

extern  AttValue_array * service_getattributes_1_svc(cstring resourceName,
						     String_array attributeNameArray , 
						     struct svc_req *rqstp) {
  AttValue_array *ptr;
  AttValue *ptr_att;
  int resource_index;
  void *value;
  int i;
  int type;
  int rc;


  /* frees previous result */
  xdr_free((xdrproc_t)  xdr_AttValue_array, (char *) &att_array);

  /*lookup for the resource index within the resource 
    server */
  resource_index = -1;
  /* The procedure should always return this pointer */
  ptr= &att_array;
  bzero(ptr,sizeof(AttValue_array));
  bzero(&att_array,sizeof(AttValue_array));


  if (resourceName == NULL) {
    DEBUG_PRINTF("service_getattribute: resource_name is a null parameter\n");
    return &att_array;
  }



  att_array.AttValue_array_len = attributeNameArray.String_array_len;  
  att_array.AttValue_array_val = (AttValue *) malloc(sizeof(AttValue) 
						     *attributeNameArray.String_array_len);
  bzero(ptr->AttValue_array_val,(sizeof(AttValue) * attributeNameArray.String_array_len));

  /*
  fix bugId:5070438
  Java / C SDK: (Linux) gettAttributes not working
  */
 
  i = 0;
  while (i <attributeNameArray.String_array_len) {
    ptr_att=&ptr->AttValue_array_val[i];
     ptr_att->value = (char *)    malloc(MF_ATTRIBUTE_NAME_SIZE);
     bzero(ptr_att->value, MF_ATTRIBUTE_NAME_SIZE);
    
   
    rc = mfGetResourceAttributePtr(resourceName,attributeNameArray.String_array_val[i], &value, &type) ;

    if (rc != MF_SUCCESS) {
      if (rc == MF_RESOURCE_ATTRIBUTE_NOT_EXIST) {
	ptr_att->type = MF_TYPE_ATTRIBUTE_NOT_EXIST;

	DEBUG_PRINTF4(" service_getattributes: for resource_name %s, attribute_name %s  not found, (rc = %d) \n", 
		      resourceName,
		      attributeNameArray.String_array_val[i],
		      rc);

	/* fix of bugId  5077608:
	 Actually, the implementation in C of the getAttributes function 
	 returns the attribute list as soon as an error occurs while getting 
	 an attribute value.
	 Whereas in JMX, getAttributes is supposed to parse the 
	 whole list of attributes
	*/
	i++;
	continue;
      }

      if (rc == MF_RESOURCE_OBJECT_NOT_EXIST) {
	  /*fix bugId 5077195
	    InstanceNotFound never raised with getAttributes */
	   att_array.AttValue_array_len= 0;
	  DEBUG_PRINTF3("service_getattribute: resource_name %s not found rc=%d\n", resourceName, rc);
	  return &att_array;
      } 

      if (rc == MF_RESOURCE_GETTER_CALLBACK_NOT_EXIST) {
	  att_array.AttValue_array_len = 0;
	  DEBUG_PRINTF3(" service_getattribute: resource_name %s (getter callback not exist) not found rc= %d\n", 
			resourceName,rc);
	  return &att_array;
      } 
    }


    ptr_att->value= (char *) malloc(MF_ATTRIBUTE_NAME_SIZE);
    bzero(ptr_att->value,MF_ATTRIBUTE_NAME_SIZE);
    strcpy(ptr_att->value,"dummy");
    /* perform the cast of the resource value, which is
       transformed into a char array in ptr->value */
      
    ptr_att->type = type;
    castresource2string(ptr_att->value,type, value);

    /*fix bugId: 5071756
      C SDK getAttributes causing crash of the agent (X86)
    */

    DEBUG_PRINTF5(" service_getattributes:%s %s=%s , type = %d\n", resourceName,attributeNameArray.String_array_val[i],ptr_att->value,ptr_att->type); 

  i++ ;
  }
  
  return &att_array;
}




extern  AttValue * service_invoke_1_svc(cstring resourceName, 
					cstring methodName, 
					AttValue_array paramsArray, 
					String_array signatureArray, 
					struct svc_req *rqstp) {


  AttValue *ptr;
  int resource_index;
  void *value;
  int rc;
  int type;



  /*lookup for the resource index within the resource 
    server */
  resource_index = -1;
 
  /* The procedure should always return this pointer */
  ptr = &att;
  xdr_free((xdrproc_t) xdr_AttValue, (char *)  &att) ;

  att.value = (char *)    malloc(MF_ATTRIBUTE_NAME_SIZE);
  att.type = 0;
  bzero(att.value, MF_ATTRIBUTE_NAME_SIZE);

  /* copy a dummy string due to the rpc exhanges */
  strcpy(att.value,"dummy");


 if (resourceName == NULL) {
      att.type = MF_TYPE_OBJECT_NOT_EXIST;
      DEBUG_PRINTF("service_invoke: resourceName is a null parameter\n");
      return &att;
  }



  if (methodName == NULL) {
      att.type = MF_TYPE_OBJECT_NOT_EXIST;
      DEBUG_PRINTF("service_invoke: attributeName is a null parameter\n");
      return &att;
  }


  rc = mfInvokeResource(resourceName,
			methodName, 
			paramsArray, 
			signatureArray,
			value, &type) ;

  if (rc != MF_SUCCESS) {
    if (rc == MF_RESOURCE_OBJECT_NOT_EXIST) {
      att.type = MF_TYPE_OBJECT_NOT_EXIST;
      DEBUG_PRINTF2(" service_invoke: resource_name %s not found\n", resourceName);
    } 

    if (rc == MF_RESOURCE_METHOD_NOT_EXIST) {
      att.type = MF_TYPE_METHOD_NOT_EXIST;
      DEBUG_PRINTF2(" service_invoke: resource_name %s not found\n", resourceName);
    } 

    if (rc == MF_RESOURCE_GETTER_CALLBACK_NOT_EXIST) {
      att.type = MF_TYPE_CALLBACK_NOT_EXIST;
      DEBUG_PRINTF2(" service_invoke: resource_name %s not found\n", resourceName);
    }

    return &att; 

  }

  /* invoke has been successful */

 /* perform the cast of the resource value, which is
     transformed into a char array in ptr->value */
  
  return &att;

}


