/*!
  \file objectpath.c
  \brief Native CMPIObjectPath implementation.

  This is the native CMPIObjectPath implementation as used for remote
  providers. It reflects the well-defined interface of a regular
  CMPIObjectPath, however, it works independently from the management broker.
  
  It is part of a native broker implementation that simulates CMPI data
  types rather than interacting with the entities in a full-grown CIMOM.

  (C) Copyright IBM Corp. 2003
  (C) Copyright Intel Corp. 2005
 
  THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE 
  ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE 
  CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
 
  You can obtain a current copy of the Eclipse Public License from
  http://www.opensource.org/licenses/eclipse-1.0.php

  \author Frank Scheffler
  $Revision: 1.5 $
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cmcidt.h"
#include "cmcift.h"
#include "cmcimacs.h"
#include "native.h"
#include "utilft.h"

#ifdef DMALLOC
#include "dmalloc.h"
#endif

extern void *newList();
extern char *pathToChars(CMPIObjectPath * cop, CMPIStatus * rc, char *str,
								 int uri);
void pathToXml(UtilStringBuffer *sb, CMPIObjectPath *cop);
UtilList *getNameSpaceComponents(CMPIObjectPath * cop);

extern char *keytype2Chars(CMPIType type);
extern char *value2Chars(CMPIType type, CMPIValue * value);


struct native_cop {
	CMPIObjectPath cop;
	char * nameSpace;
	char * classname;
	struct native_property * keys;
};


static struct native_cop * __new_empty_cop ( const char *,
					     const char *,
					     CMPIStatus * );

/****************************************************************************/


static CMPIStatus __oft_release ( CMPIObjectPath * cop )
{
	struct native_cop * o = (struct native_cop *) cop;

	if ( o ) {
 
		if (o->classname) free ( o->classname );
		if (o->nameSpace) free ( o->nameSpace );
 		propertyFT.release ( o->keys );

		free ( o );
 
 		CMReturn ( CMPI_RC_OK );
	}

	CMReturn ( CMPI_RC_ERR_FAILED );
}


static CMPIObjectPath * __oft_clone ( CMPIObjectPath * cop, CMPIStatus * rc )
{
	CMPIStatus tmp;
	struct native_cop * o   = (struct native_cop *) cop;
	struct native_cop * new = __new_empty_cop ( o->nameSpace,
						    o->classname,
						    &tmp );

	if ( tmp.rc == CMPI_RC_OK ) {
		new->keys = propertyFT.clone ( o->keys, rc );

	} else
                CMSetStatus ( rc, tmp.rc );

	return (CMPIObjectPath *) new;
}



static CMPIStatus __oft_setNameSpace ( CMPIObjectPath * cop,
				       const char * nameSpace )
{
	struct native_cop * o = (struct native_cop *) cop;

	if ( o ) {
		char * ns = ( nameSpace )? strdup ( nameSpace ): NULL;
  
		if ( o->nameSpace )
		     free ( o->nameSpace );
	    o->nameSpace = ns;
	}
	CMReturn ( CMPI_RC_OK );
}


static CMPIString * __oft_getNameSpace ( CMPIObjectPath * cop,
					 CMPIStatus * rc )
{
	struct native_cop * o = (struct native_cop *) cop;

	return native_new_CMPIString ( o->nameSpace, rc );
}


static CMPIStatus __oft_setHostName ( CMPIObjectPath * cop, const char * hn )
{
	CMReturn ( CMPI_RC_ERR_NOT_SUPPORTED );
}


static CMPIString * __oft_getHostName ( CMPIObjectPath * cop,
					CMPIStatus * rc )
{
	CMSetStatus ( rc, CMPI_RC_ERR_NOT_SUPPORTED );
	return NULL;
}


static CMPIStatus __oft_setClassName ( CMPIObjectPath * cop,
				       const char * classname )
{
	struct native_cop * o = (struct native_cop *) cop;

	if ( o ) {
		char * cn = ( classname )? strdup ( classname ): NULL;
  
		if ( o->classname )
		    free ( o->classname );
	    o->classname = cn;
	}

	CMReturn ( CMPI_RC_OK );
}


static CMPIString * __oft_getClassName ( CMPIObjectPath * cop,
					 CMPIStatus * rc )
{
	struct native_cop * o = (struct native_cop *) cop;

	return native_new_CMPIString ( o->classname, rc );
}


static CMPIStatus __oft_addKey ( CMPIObjectPath * cop,
				 const char * name,
				 CMPIValue * value,
				 CMPIType type )
{
	struct native_cop * o = (struct native_cop *) cop;

	CMReturn ( ( propertyFT.addProperty ( &o->keys,
					      name,
					      type,
					      CMPI_keyValue,
					      value ) )?
		   CMPI_RC_ERR_ALREADY_EXISTS: 
		   CMPI_RC_OK );
}


static CMPIData __oft_getKey ( CMPIObjectPath * cop,
			       const char * name,
			       CMPIStatus * rc )
{
	struct native_cop * o = (struct native_cop *) cop;

	return propertyFT.getDataProperty ( o->keys, name, rc );
}


static CMPIData __oft_getKeyAt ( CMPIObjectPath * cop, 
				 unsigned int index,
				 CMPIString ** name,
				 CMPIStatus * rc )
{
	struct native_cop * o = (struct native_cop *) cop;

	return propertyFT.getDataPropertyAt ( o->keys, index, name, rc );
}


static unsigned int __oft_getKeyCount ( CMPIObjectPath * cop, CMPIStatus * rc )
{
	struct native_cop * o = (struct native_cop *) cop;
  
	return propertyFT.getPropertyCount ( o->keys, rc );
}


static CMPIStatus __oft_setNameSpaceFromObjectPath ( CMPIObjectPath * cop,
						     CMPIObjectPath * src )
{
	struct native_cop * s = (struct native_cop *) src;
	return __oft_setNameSpace ( cop, s->nameSpace );
}

static CMPIString *__oft_toString(CMPIObjectPath * cop, CMPIStatus * rc);

static struct native_cop * __new_empty_cop ( const char * nameSpace,
					     const char * classname,
					     CMPIStatus * rc )
{
	static CMPIObjectPathFT const oft = { 
		NATIVE_FT_VERSION,
		__oft_release,
		__oft_clone,
		__oft_setNameSpace,
		__oft_getNameSpace,
		__oft_setHostName,
		__oft_getHostName,
		__oft_setClassName,
		__oft_getClassName,
		__oft_addKey,
		__oft_getKey,
		__oft_getKeyAt,
		__oft_getKeyCount,
		__oft_setNameSpaceFromObjectPath,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL,
		__oft_toString
	};
        
	static CMPIObjectPath const o = {
		"CMPIObjectPath",
		(CMPIObjectPathFT*)&oft
	};

	struct native_cop * cop =
	      (struct native_cop *) calloc ( 1, sizeof ( struct native_cop ) );

	cop->cop       = o;
	cop->classname = ( classname )? strdup ( classname ): NULL;
	cop->nameSpace = ( nameSpace )? strdup ( nameSpace ): NULL;

	CMSetStatus ( rc, CMPI_RC_OK );
	return cop;
}


CMPIObjectPath * newCMPIObjectPath ( const char * nameSpace, 
					     const char * classname,
					     CMPIStatus * rc )
{
	return (CMPIObjectPath *) __new_empty_cop ( nameSpace,
						    classname,
						    rc );
}

void sameReleaseCMPIString( CMPIString *str )
{
    // If we are not freeing a NULL pointer ...
    if( str )
    {
        // Free dynamically allocated memory.
        CMRelease( str );
    }
}

int sameCompareCMPIString( CMPIString *str1, CMPIString *str2 )
{
    int result=1;

    if( !str1 || !str2 ||
        ( strcmp( CMGetCharsPtr( str1, NULL ),
                  CMGetCharsPtr( str2, NULL ) ) != 0 ) )
    {
        result=0;
    }

    /* Free up dynamically allocated memory if needed. */
    sameReleaseCMPIString( str1 );
    sameReleaseCMPIString( str2 );

    return result;
}

int sameCMPIObjectPath (const CMPIObjectPath *cop1, const CMPIObjectPath *cop2)
{
   CMPIString *keyname;
   CMPIData   data1, data2;
   CMPIStatus status;
   struct native_cop *ncop1 = (struct native_cop *)cop1;
   struct native_cop *ncop2 = (struct native_cop *)cop2;
   unsigned int i, m;
   char *cv1, *cv2;

   /* Check if name spaces are the same */
   if (strcasecmp(ncop1->nameSpace, ncop2->nameSpace) != 0)
      return 0;

   /* Check if classnames are the same */
   if (strcasecmp(ncop1->classname, ncop2->classname) != 0)
      return 0;

   /* Check if the key count is the same */
   m = propertyFT.getPropertyCount(ncop1->keys, NULL);
   if (m != propertyFT.getPropertyCount(ncop2->keys, NULL)) 
      return 0;

   /* Check on each key */
   for (i = 0; i < m; i++) {
      data1 = propertyFT.getDataPropertyAt(ncop1->keys, i, &keyname, &status );

      /* check if key exists in both */
      if (status.rc != CMPI_RC_OK)
      {
        // Free up dynamically allocated memory
        sameReleaseCMPIString( keyname );
        return 0;
      }

      // This in effect verifies the keynames are the same. We are searching
      // for the keyname of cop1 in cop2.  
      data2 = propertyFT.getDataProperty(ncop2->keys,
					 CMGetCharsPtr( keyname, NULL ),
					 &status );

      // Free up dynamically allocated memory
      sameReleaseCMPIString( keyname );

      /* check if key exists in both */
      if (status.rc != CMPI_RC_OK)
	  return 0;

      /* Check if the values are the same */
      if( data1.type  != data2.type       ||
          data1.state != data2.state  ){
	      return 0;
      } else {
	      cv1 = value2Chars(data1.type, &data1.value);
	      cv2 = value2Chars(data2.type, &data2.value);
	      if (strcmp(cv1,cv2) == 0) {
		      if (cv1) free(cv1);
		      if (cv2) free(cv2);
	      } else {
		      if (cv1) free(cv1);
		      if (cv2) free(cv2);
		      return 0;
	      }
      }
   }

   return 1;
}

char *pathToChars(CMPIObjectPath * cop, CMPIStatus * rc, char *str, int uri)
{
//            "//atp:9999/root/cimv25:TennisPlayer.first="Patrick",last="Rafter";

   CMPIString *ns;
   CMPIString *cn;
   CMPIString *name;
   CMPIData data;
   unsigned int i, m, s;
   char *v;
   char *colon = (uri) ? "%3A" : ":";
   
   *str = 0;

   ns = cop->ft->getNameSpace(cop, rc);
   cn = cop->ft->getClassName(cop, rc);
   
   if (ns && ns->hdl && *(char*)ns->hdl) {
      if (!uri)
	  strcpy(str,(char*)ns->hdl);
      else {
         char *cns=(char*)ns->hdl;
         for (s=i=0, m=strlen(cns); i<m; i++,s++) {
            if (cns[i]=='/') {
               str[s++]='%';
               str[s++]='2';
               str[s]='F';
            }
            else
	       str[s]=cns[i];    
         } 
         str[s]=0;   
      }
      strcat(str,colon);
   }   
   
   if (ns) CMRelease(ns);
   strcat(str, (char *) cn->hdl);
   CMRelease(cn);
   
   for (i = 0, m = cop->ft->getKeyCount(cop, rc); i < m; i++) {
      data = cop->ft->getKeyAt(cop, i, &name, rc);
      strcat(str, i ? "," : ".");
      strcat(str, (char *) name->hdl);
      strcat(str, (uri) ? "%3D" : "=");
      v = value2Chars(data.type, &data.value);
      if (data.type & (CMPI_INTEGER | CMPI_REAL))
         strcat(str, v);
      else {
	 strcat(str, "\"");
         strcat(str, v);
	 strcat(str, "\"");
      }
      free(v);
      CMRelease(name);
   };
 
   return str;
}

static CMPIString *__oft_toString(CMPIObjectPath * cop, CMPIStatus * rc)
{
   char str[4096] = { 0 };
   pathToChars(cop, rc, str,0);
   return native_new_CMPIString(str, rc);
}

const char *getNameSpaceChars(CMPIObjectPath * cop)
{
   if (cop == NULL) return NULL;

	struct native_cop * o = (struct native_cop *) cop;
   return o->nameSpace;
}

UtilList *getNameSpaceComponents(CMPIObjectPath * cop)
{
   UtilList *ul=newList();
   CMPIString *nss=__oft_getNameSpace(cop, NULL);
   int s=0,i,m;
   char nsc[256],*ns;
   
   if (nss && nss->hdl) {
      ns=(char*)nss->hdl;
      for (s=i=0, m=strlen(ns); i<m; i++,s++) {
         if (ns[i]=='/') {
            nsc[s]=0;
            ul->ft->append(ul,strdup(nsc));
            s=-1;
         }
         else nsc[s]=ns[i];    
      } 
      nsc[s]=0;
   }   
   
   if (s) ul->ft->append(ul,strdup(nsc));
   if (nss) CMRelease(nss);
   return ul;
}

void pathToXml(UtilStringBuffer *sb, CMPIObjectPath *cop)
{
   int i,s;
   CMPIData data;
   CMPIString *name;
   char *cv;

   for (i=0,s=__oft_getKeyCount(cop,NULL); i<s; i++) {
      data=__oft_getKeyAt(cop,i,&name,NULL);
      sb->ft->append3Chars(sb,"<KEYBINDING NAME=\"",(char*)name->hdl,"\">");
      if (data.type==CMPI_ref) {
         CMPIObjectPath *ref=data.value.ref;           
         sb->ft->appendChars(sb, "<VALUE.REFERENCE><INSTANCEPATH>\n");
         
         CMPIString *hn = __oft_getHostName(ref, NULL);
         if (hn != NULL) {
            sb->ft->append3Chars(sb,"<NAMESPACEPATH><HOST>",hn->hdl,"</HOST>\n");
            CMRelease(hn);
         }
         else sb->ft->append3Chars(sb,"<NAMESPACEPATH><HOST>", "localhost","</HOST>\n");
            
         sb->ft->appendChars(sb, "<LOCALNAMESPACEPATH>\n");
         CMPIString *nss=__oft_getNameSpace(ref, NULL);
         if (nss && nss->hdl) {
             char *p1 = (char *)nss->hdl;
             char *p2;
             while ((p2 = strchr(p1, '/')) != NULL) {
                *p2 = 0;
                sb->ft->append3Chars(sb,"<NAMESPACE NAME=\"",p1,
                                       "\"></NAMESPACE>\n");
                p1 = p2 + 1;
             }
             sb->ft->append3Chars(sb,"<NAMESPACE NAME=\"",p1,
                                    "\"></NAMESPACE>\n");
             CMRelease(nss);
         }             
         sb->ft->appendChars(sb,"</LOCALNAMESPACEPATH></NAMESPACEPATH>\n");
            
         CMPIString *cn=__oft_getClassName(ref, NULL);
         sb->ft->append3Chars(sb,"<INSTANCENAME CLASSNAME=\"",(char*)cn->hdl,"\">");
         pathToXml(sb,ref);                       
         sb->ft->appendChars(sb,"</INSTANCENAME></INSTANCEPATH></VALUE.REFERENCE>");
         CMRelease(cn);
      }
      else {
         cv = value2Chars(data.type,&data.value);
         sb->ft->append5Chars(sb,"<KEYVALUE VALUETYPE=\"",
                                 keytype2Chars(data.type),"\">",cv,
                                 "</KEYVALUE>");
        if (cv) free (cv);
      }

      sb->ft->appendChars(sb,"</KEYBINDING>\n");
      if (name) CMRelease(name);
   }
}

/****************************************************************************/

/*** Local Variables:  ***/
/*** mode: C           ***/
/*** c-basic-offset: 8 ***/
/*** End:              ***/
