#include <WScom.h>
#include <WSCfunctionList.h>
#include <WSCbase.h>
//----------------------------------------------------------
//Function for the event procedure
//----------------------------------------------------------
#include <WSCbaseList.h>
#include <newwin000.h>
#include <WSCRbaseList.h>

extern WSCstring ipaddr;
void udp_read(WSCbase* object){
  //do something...
  //受け取ったデータを 
  //WSGIappObjectList()->addRemoteInstanceData(WSCremoteInstanceData* idata);
  //WSGIappObjectList()->setRemoteInstanceListUpdated(True);
  //する。 

  WSCuchar buffer[256];
  long ret = newvudp_000->read(buffer,256);

//printf("udp_read!!! %x %x\n",buffer[1],buffer[0]);
  if (ret != 256){
    return;
  }

  WSCushort port = buffer[5] *256 + buffer[4];
//printf("port=%d\n",port);
  char magic0 = buffer[0];
  char magic1 = buffer[1];
  char magic2 = buffer[2];
  char cmd = buffer[3];
  char addr[256];
  char cname[64];
  char iname[64];
  char pname[64];
  memcpy(addr,&buffer[6],26);
  if (magic0 != 'w' ||
      magic1 != 's' ||
      magic2 != 'a'){
fprintf(stderr,"wsagent: error. reveive bad magic=%c%c%c\n",magic0,magic1,magic2);
    return;
  }
  addr[31] = 0;
  if (cmd == 'A'){
    memcpy(cname,&buffer[32],48);
    cname[63] = 0;
    memcpy(iname,&buffer[80],64);
    iname[63] = 0;
    memcpy(pname,&buffer[144],64);
    pname[63] = 0;

//printf("from addr=%s\n",addr);
//printf("cname=%s iname=%s p=name%s\n",cname,iname,pname);
    if (!strcmp(addr,"127.0.0.1")){
      strcpy(addr,newvudp_000->getDestAddr());
//printf("set addr=%s\n",addr);
    }

    WSClistData* rlist = WSGIappObjectList()->getRemoteInstanceList();
    long num = rlist->getNum();
    long i;
    for(i=0; i<num; i++){
      WSCremoteInstanceData* rinst =
          (WSCremoteInstanceData*)rlist->getData(i);
      if (!strcmp(rinst->getPublicInstanceName(),pname) &&
          !strcmp(rinst->getClassName(),cname)&&
          !strcmp(rinst->getAddr(),addr)&&
          !strcmp(rinst->getInstanceName(),iname)&&
          rinst->getPort() == port){
//printf("udp_read updated..!!! exit1 %d %s %s\n",port,addr,iname);
        return;
      }
      if (!strcmp(rinst->getPublicInstanceName(),pname) &&
          !strcmp(rinst->getClassName(),cname)&&
          !strcmp(rinst->getAddr(),"")&&
          !strcmp(ipaddr.getString(),addr)&&
          !strcmp(rinst->getInstanceName(),iname)&&
          rinst->getPort() == port){
//printf("udp_read updated..!!! exit2 %d %s %s\n",port,addr,iname);
        return;
      }
    }
//printf("udp_read updated..!!! %d %s %s\n",port,addr,iname);

    WSCremoteInstanceData rinst;
    rinst.setPort(port);
    rinst.setAddr(addr);
    rinst.setClassName(cname);
    rinst.setInstanceName(iname);
    rinst.setPublicInstanceName(pname);

    WSGIappObjectList()->addRemoteInstanceData(&rinst);
    WSGIappObjectList()->setRemoteInstanceListUpdated(True);
  }else
  if (cmd == 'U'){
//printf("wsagent: update request reveived.... \n");
    memcpy(cname,&buffer[32],48);
    cname[63] = 0;
    memcpy(iname,&buffer[80],64);
    iname[63] = 0;
    memcpy(pname,&buffer[144],64);
    pname[63] = 0;
    if (!strcmp(addr,"127.0.0.1")){
      strcpy(addr,newvudp_000->getDestAddr());
    }
    if (!strcmp(addr,"127.0.0.1")){
      return;
    }

    WSCRbaseList* orb = new WSCRbaseList();
    if (orb == NULL){
      return;
    }

    orb->setPort(WS_DEFAULT_AGENT_PORT);
    orb->setAddr(addr);
//printf("update sendto=%s %d\n",addr,WS_DEFAULT_AGENT_PORT);
    WSClistData* list = WSGIappObjectList()->getRemoteInstanceList();
    long i; 
    long num = list->getNum();
    WSCremoteInstanceData rinst;

    for(i=0; i<num; i++){
      WSCremoteInstanceData* inst = (WSCremoteInstanceData*)(*list)[i];
      if (inst != NULL){
        long ret = orb->addRemoteInstanceData(inst);
        if (ret != WS_NO_ERR){
//printf("remote call error...\n");
          delete orb;
          return;
        }
      }
    }
    if (orb != NULL){
      delete orb;
    }
  }

}
static WSCfunctionRegister  op("udp_read",(void*)udp_read);
