#ifndef __SVDRPCLIENT_H
#define __SVDRPCLIENT_H

#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>

#define SVDRPCONNECT 220
#define SVDRPDISCONNECT 221
#define CMDSUCCESS 250

class cSVDRPClient {
 private:
    int sock;
public:
    bool bConnected;

    cSVDRPClient(int Port)
	{
	    bConnected = false;
	    sock  = socket(PF_INET, SOCK_STREAM, 0);
	    if (sock < 0) 
	    {
		esyslog("EPGSearch: error creating socket!");
		return;
	    }

	    struct sockaddr_in AdrSock;
	    AdrSock.sin_family = AF_INET;
	    AdrSock.sin_port   = htons(EPGSearchConfig.SVDRPPort);
	    inet_aton("127.0.0.1", &AdrSock.sin_addr);
/*
	    if(getAddrFromString("localhost",&AdrSock) == -1)
	    {
		esyslog("EPGSearch: could not resolve IP for \"localhost\"");
		LogFile.Log(1,"could not resolve IP for \"localhost\"");
		return;
	    }
*/
	    if (connect(sock, (struct sockaddr*)&AdrSock, sizeof(AdrSock)) == -1)
	    {
		esyslog("EPGSearch: error connecting to socket!");
		LogFile.Log(1,"error connecting to socket!");
		return;
	    }
	    bConnected = (Receive() == SVDRPCONNECT);
	    if (!bConnected)
	    {
		esyslog("EPGSearch: could not connect to VDR!");
		LogFile.Log(1,"could not connect to VDR!");
	    }
	}

    long getAddrFromString(char* hostnameOrIp, struct sockaddr_in* addr)
	{
	    unsigned long ip;

	    struct hostent * he;

	    if(hostnameOrIp==NULL || addr==NULL)
		return -1;

	    ip=inet_addr(hostnameOrIp);

	    if(ip!=INADDR_NONE)
	    {
		addr->sin_addr.s_addr=ip;		
		return 0;
	    }
	    else
	    {
		he=gethostbyname(hostnameOrIp);
		if(he==NULL)
		    return -1;
		else
		    memcpy(&(addr->sin_addr),he->h_addr_list[0],4);
		return 0;
	    }
	}

    bool SendCmd(char* cmd) 
	{
	    if (!bConnected)
		return false;

	    char* szCmd = NULL;

	    asprintf(&szCmd, "%s\r\n", cmd);
	    Send(szCmd);
	    free(szCmd);
	    bool cmdret = (Receive() == CMDSUCCESS);

	    asprintf(&szCmd, "QUIT\r\n");
	    Send(szCmd);
	    free(szCmd);
	    if (Receive() != SVDRPDISCONNECT)
	    {
		esyslog("EPGSearch: could not disconnect!");
		LogFile.Log(1,"could not disconnect!");
	    }
	    
	    close(sock);
	    return cmdret;
	}
    bool Send(char* szSend) 
	{
	    int length = strlen(szSend);
	    int sent = 0;
	    do
	    {
		sent += send(sock, szSend + sent, length - sent, 0);
		if( sent < 0 )
		{
		    esyslog("EPGSearch: error sending command!");
		    LogFile.Log(1,"error sending command!");
		    return false;
		}
	    }
	    while ( sent < length );
	    return true;
	}
    long Receive() 
	{
	    char* csResp = strdup("");
	    char ch;
	    long rc = 0;

	    bool bCheckMultiLine = true;

	    while(bCheckMultiLine)
	    {
		while( strlen(csResp) < 2 || strcmp(csResp + strlen(csResp) - 2, "\r\n") != 0)
		{
		    if (recv(sock, &ch, 1, 0 ) < 0)
		    {
			esyslog("EPGSearch: error receiving response!");
			LogFile.Log(1,"error receiving response!");
			return -1;
		    }
		    char* Temp = NULL;
		    asprintf(&Temp, "%s%c", csResp, ch);
		    free(csResp);
		    csResp = Temp;
		}
		if( csResp[3] == ' ' )
		{
		    bCheckMultiLine = false;
		    rc = atol(csResp);
		}
		free(csResp);
		csResp = strdup("");
	    }		
	    free(csResp);
	    return rc;
	}
};

#endif
